[尝试通过API调用将@ObservedObject数据传递到SwiftUI内容视图。
使用API调用中的打印命令,我可以看到数据已提取并解码正常。
但是尝试将@Published数据传递到ContentView进行显示会产生错误:Instance member 'byCountry' cannot be used on type 'DataModel'
(DataModel是数据的结构)。
这里的数据结构:
class DataModel: Decodable {
let global : Global
let byCountry: [ByCountry]
let date: String
enum CodingKeys: String, CodingKey {
case global = "Global"
case byCountry = "Countries"
case date = "Date"
}
struct Global: Decodable {
let globalNC: Int
let globalTC: Int
let globalND: Int
let globalTD: Int
let globalNR: Int
let globalTR: Int
enum CodingKeys: String, CodingKey {
case globalNC = "NewConfirmed"
case globalTC = "TotalConfirmed"
case globalND = "NewDeaths"
case globalTD = "TotalDeaths"
case globalNR = "NewRecovered"
case globalTR = "TotalRecovered"
}
}
struct ByCountry: Decodable {
let cntry: String
let ccode: String
let slug: String
let cntryNC: Int
let cntryTC: Int
let cntryND: Int
let cntryTD: Int
let cntryNR: Int
let cntryTR: Int
let date: String
enum CodingKeys: String, CodingKey {
case cntry = "Country"
case ccode = "CountryCode"
case slug = "Slug"
case cntryNC = "NewConfirmed"
case cntryTC = "TotalConfirmed"
case cntryND = "NewDeaths"
case cntryTD = "TotalDeaths"
case cntryNR = "NewRecovered"
case cntryTR = "TotalRecovered"
case date = "Date"
}
}
}
这里是API调用:
class APICall : ObservableObject, Identifiable {
@Published var dataPull = DataModel.self
init() {
let urlCall = URL(string: "https://api.covid19api.com/summary")
guard urlCall != nil else {
print("Error reaching API")
return
}
let session = URLSession.shared
let dataTask = session.dataTask(with: urlCall!) { (data, response, error) in
if error == nil && data != nil {
let decoder = JSONDecoder()
do {
let dataPull = try decoder.decode(DataModel.self, from: data!)
print(dataPull.global.globalNC)
}
catch {
print("Server busy, try again in 5 min.")
}
DispatchQueue.main.async {
self.dataPull = self.dataPull
}
}
}
dataTask.resume()
}
}
在APICall中打印提取和解码的数据有效并且正确。
这里是ContentView代码:
import SwiftUI
struct ContentView: View {
@ObservedObject var apiCall = APICall()
var body: some View {
Text($apiCall.dataPull.byCountry[35].cntry)
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
}
简单文本显示Text($apiCall.dataPull.byCountry[35].cntry)
会同时提示Initializer 'init(_:)' requires that 'Binding<String>' conform to 'StringProtocol'
错误,和Instance member 'byCountry' cannot be used on type 'DataModel'
错误。
由于我是初学者,无法找到错误问题的答案,并且想象这是直接失败。
其他问题...我使用了一个示例,如图所示在APICall中实现了“ init(){..”。但是我还打算在ContentView中添加一个按钮,以在按钮操作时执行APICall来刷新数据。当使用“ init()”代替函数调用时如何执行?
感谢任何帮助。谢谢。
两件事...
class APICall : ObservableObject, Identifiable {
@Published var dataPull: DataModel? = nil // here !!
和
struct ContentView: View {
@ObservedObject var apiCall = APICall()
var body: some View {
if apiCall.dataPull != nil { // only when there is data
// !! pay attention - you hardcoded 35th element, but it
// !! might be absent in response - then crash
Text(apiCall.dataPull!.byCountry[35].cntry) // here !!
} else {
Text("Loading...")
}
}
}