我会try 使用MVVM获取Pokemon的一个API的数据,我使用我的MainViewModel执行请求,如果我在MainViewModel中打印Pokemon数组,我会得到数组,但当我将数组发送给代表时,我无法在MainViewDelegate中显示该array. 向你问好.

当我在MainViewModel中打印数据时,得到的数据如下所示.

[Pokemon.PokemonModel(name: "bulbasaur", imageURL: "https://pokeapi.co/api/v2/pokemon/1/"), Pokemon.PokemonModel(name: "ivysaur", imageURL: "https://pokeapi.co/api/v2/pokemon/2/"), Pokemon.PokemonModel(name: "venusaur", imageURL: "https://pokeapi.co/api/v2/pokemon/3/")]
//  MainViewController.swift
override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .systemGray6

        setUpView()
        setUpLayout()
        viewModel.fetchPokemon()
    }
//  MainViewModel.swift
import UIKit

class MainViewModel {
    let pokemonUrl = "https://pokeapi.co/api/v2/pokemon?limit=898&offset=0"
    var delegate: MainViewDelegate?

    func getPokemonImage() -> UIImage {
        return UIImage(named: "pikachu")!
    }

    func getTitleButton() -> String {
        return "Pokemon"
    }

    func fetchPokemon() {
        performRequest(with: pokemonUrl)
    }

    private func performRequest(with urlString: String) {
        // 1. Create/get URL
        if let url = URL(string: urlString) {
            // 2. Create URLSession
            let session = URLSession(configuration: .default)
            // 3. Give the session a task
            let task = session.dataTask(with: url) { [self] data, response, error in
                if error != nil {
                    delegate?.didFailWithError(error: error!)
                }

                if let safeData = data {
                    if let pokemon = self.parseJSON(pokemonData: safeData) {
                        delegate?.didUpdatePokemon(pokemons: pokemon)
                        print(pokemon)
                    }
                }
            }
            // 4. Start the task
            task.resume()
        }
    }

    private func parseJSON(pokemonData: Data) -> [PokemonModel]? {
        let decoder = JSONDecoder()
        do {
            let decodeData = try decoder.decode(PokemonData.self, from: pokemonData)
            let pokemon = decodeData.results?.compactMap({
                if let name = $0.name, let imageURL = $0.url {
                    return PokemonModel(name: name, imageURL: imageURL)
                }
                return nil
            })
            return pokemon
        } catch {
            return nil
        }
    }
    
}
//  MainView+Delegates.swift
import UIKit

// MARK: - Custom Delegates

extension MainViewController: MainViewDelegate {
    func didFailWithError(error: Error) {
        print(error)
    }

    func didUpdatePokemon(pokemons: [PokemonModel]) {
        print(pokemons)
    }
}


extension Collection where Indices.Iterator.Element == Index {
    public subscript(safe index: Index) -> Iterator.Element? {
        return (startIndex <= index && index < endIndex) ? self[index] : nil
    }
}

// Get 4 items
extension Collection {
    func choose(_ n: Int) -> Array<Element> {
        Array(shuffled().prefix(n))
    }
}
//
//  MainView+Protocols.swift
//

import Foundation

// MARK: - Que es lo que debe de tener

protocol MainViewDelegate {
    func didUpdatePokemon(pokemons: [PokemonModel])
    func didFailWithError(error: Error)
}
//
//  PokemonData.swift

import UIKit

// MARK: - PokemonData

struct PokemonData: Codable {
    let results: [Result]?
}

struct Result: Codable {
    let name: String?
    let url: String?
}
//
//  PokemonModel.swift

import Foundation

struct PokemonModel {
    let name: String
    let imageURL: String
}

我try 使用委托来使用数据.

推荐答案

您的视图模型有一个可选的委托属性,但是(在显示的代码中)您从未将该委托属性设置为提供委托服务的任何对象.如果没有设置,所有对委托函数的调用都将失败,但由于您是可选的链接它们,所以不会收到任何失败消息.因为您确实有有效的数据打印,所以可以工作.

当您初始化视图模型时(您也没有显示它!),您需要初始化"Delegate"属性.您可以通过它的初始化器或通过以下方式在‘viewDidLoad`中执行此操作

viewModel.delegate = self

这将允许您直通调用委托方法.

Ios相关问答推荐

OnTapGesture在其修改的视图外部触发

Swift-如何通过Case Let访问模型变量

在 Swift 中 @MainActor 似乎被 withCheckedContinuation 而不是其他异步调用继承是巧合吗?

UIView 倒置旋转时的zoom 问题

从父母到子元素的 Swift Pass 事件

如何在 Swift 上的 sendSynchronousRequest 中判断 Response.statusCode

缺少推送通知权利

在 Swift 中按下返回键时在文本字段之间切换

何时需要将应用程序源包含在测试目标中?

在 UITextView 中垂直居中文本

判断可选数组是否为空

如何在react 导航中获取当前路由名称?

为信用卡输入格式化 UITextField,例如 (xxxx xxxx xxxx xxxx)

iOS 应用程序中的手动语言 Select (iPhone 和 iPad)

如何从 UIPickerView 获取选定的值

IOS - 从 UITextView 中删除所有填充

如何用 CAShapeLayer 和 UIBezierPath 画一个光滑的圆?

如何删除UITableView中最后一个单元格的最后一个边框?

UITableView 中的圆形 UIImageView 没有性能影响?

iPhone UITableView.如何开启音乐 App 之类的单字母字母列表?