【问题标题】:Getting API Result with closure and passing it into an other ViewController使用闭包获取 API 结果并将其传递给另一个 ViewController
【发布时间】:2022-01-14 00:30:18
【问题描述】:

我在 viewModel 中得到一个 API 结果,如下所示:

class HomePageViewModel {

var apiResult: CountryDataFromAPI?

//Getting API result via viewModel

public func getAPIResult(withOffset: Int, completion: @escaping () -> Void) {
    APIHandler.urlRequest(with: withOffset) { result in
        self.apiResult?.data.append(contentsOf: result.data)
        print("api resultdata in viewmodel is \(result.data)")
        completion()
    }
 }
}

获取 api 工作正常。在上面的代码中,我可以将语句打印为 print("api resultdata in viewmodel is (result.data)") 并查看预期的 api 结果。

当我在上面的 viewModel 中获取数据时,我在 mainViewController 中使用它。

我的 mainViewController 是用 ViewModel 初始化的

class HomePageViewController: UIViewController {

private var viewModel : HomePageViewModel
private var countryDataArray: [CountryData]?

init(with viewModel: HomePageViewModel) {
    self.viewModel = viewModel
    super.init(nibName: nil, bundle: nil)
 }
}

在我尝试从 viewModel 获取数据之前,一切正常,如下所示。 我正在尝试将 ViewModel 中的数据设置为名为 countryDataArray 的参数。但是在闭包内执行此操作时,我的打印语句“print("data in vc is (self?.viewModel.apiResult?.data)")” 打印出 nil 即使它获取了数据视图模型。

override func viewDidLoad() {
    super.viewDidLoad()
    //Getting API Result in viewDidLoad. And after getting the result, reloading the tableView.
    self.viewModel.getAPIResult(withOffset: 11) { [weak self] in
        DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: {
            self?.countryDataArray = self?.viewModel.apiResult?.data
            print("data in vc is \(self?.viewModel.apiResult?.data)")
            self?.countriesListTableView.reloadData()
        })
    }
}

为什么会发生这种情况?

PS:我的api模型如下:

struct CountryDataFromAPI: Codable {
var data: [CountryData]
}

struct CountryData: Codable,Equatable {
let name : String
let code: String
let wikiDataId: String    
}

【问题讨论】:

  • 您是否使用调试器确定self?.viewModel.apiResult?.data 的哪一部分实际上是nil?可能是selfapiResult
  • apiResult 看起来像 nil,但它在 viewModel 中有数据。由于我正在使用该 ViewModel 初始化 viewController,因此我希望它将数据包含在 viewModel 中。

标签: swift xcode api closures


【解决方案1】:

在我看来,问题出在self.apiResult?.data.append(contentsOf: result.data)

您没有为 apiResult.data 分配任何值。因为 apiResult 是 nil。

从 API 取回数据后,您必须初始化 apiResult。

【讨论】:

  • 我同意这一点,但也会争辩说,如果只使用 data,则存储 API 调用的整个结果是没有意义的。所以也许把它改成var apiResult: [CountryData]。然后可以将此属性和相同的视图控制器属性设为非可选并初始化为空数组。
  • 你们俩都完全正确。当我将 apiResult 初始化为 var apiResult: [CountryData] = [] 时,它起作用了。您能否告诉我为什么这是问题以及为什么它不能与可选选项一起使用?将数据附加到可选数组后,我不是用数据初始化它吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-27
  • 1970-01-01
  • 1970-01-01
  • 2018-10-11
  • 2019-06-30
  • 1970-01-01
相关资源
最近更新 更多