我目前正在学习SwiftUI,并且在从API打印调用的代码中遇到了问题。
NetworkManager.swift
class NetworkManager: ObservableObject {
@Published var allCountries = Countries()
func fetchAllCountries() {
if let url = URL(string: K.url) {
print(url)
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, response, error) in
if error == nil {
let decoder = JSONDecoder()
if let countriesData = data {
do {
let countries = try decoder.decode(Countries.self, from: countriesData)
DispatchQueue.main.async {
self.allCountries = countries
}
} catch {
print(error)
}
}
}
}
task.resume()
}
}
}如果我打印allCountries,我可以看到每一项
但是在我的主视图上,当我尝试打印(self.networkManager5.name)时,我得到一个索引超出范围的错误
ContentView.swift
import SwiftUI
struct ContentView: View {
@ObservedObject var networkManager = NetworkManager()
var body: some View {
Text("Hello, World!")
.onAppear {
self.networkManager.fetchAllCountries()
print(self.networkManager.allCountries[5].name)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}有人能帮我指出我哪里错了吗?
发布于 2020-04-19 07:23:26
问题出在异步fetchAllCountries上。在尝试使用结果之前,您需要等待它完成。试试这样的东西;
class NetworkManager: ObservableObject {
@Published var allCountries = Countries()
func fetchAllCountries(handler: @escaping () -> Void) {
if let url = URL(string: K.url) {
print(url)
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, response, error) in
if error == nil {
let decoder = JSONDecoder()
if let countriesData = data {
do {
let countries = try decoder.decode(Countries.self, from: countriesData)
DispatchQueue.main.async {
self.allCountries = countries
return handler()
}
} catch {
print(error)
}
}
}
handler()
}
task.resume()
}
}
}
struct ContentView: View {
@ObservedObject var networkManager = NetworkManager()
var body: some View {
Text("Hello, World!")
.onAppear {
self.networkManager.fetchAllCountries() {
print(self.networkManager.allCountries[5].name)
}
}
}
}发布于 2020-04-19 13:00:23
您试图过早地访问.allCountries,因为.fetchAllCountries是一个很长的(相对)异步操作。
解决方案是向获取国家添加显式观察者,如下所示
var body: some View {
Text("Hello, World!")
.onAppear {
self.networkManager.fetchAllCountries()
}
.onReceive(networkManager.$allCountries) { countries in
print(countries[5].name) // assuming Countries support subscript
}
}https://stackoverflow.com/questions/61297467
复制相似问题