簡體   English   中英

將解碼后的 JSON 數據傳遞給 SwiftUI ContentView

[英]Passing Decoded JSON Data to SwiftUI ContentView

API 調用和 JSON 解碼工作正常,因為我可以毫無問題地將 JSON 數據集中的任何項目打印到控制台。

這是 API 調用和測試打印:

import Foundation
import SwiftUI
import Combine

class APICall : ObservableObject {

    @Published var summary: Summary?

        init () {
            pullSummary()
        }

    func pullSummary() {
        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 summary = try decoder.decode(Summary.self, from: data!)
                    print(summary.byCountry[40].cntry as Any)
                    DispatchQueue.main.async {
                        self.summary = summary
                    }
                }
                catch {
                    print("Server busy, try again in 5 min.")
                }
            }
        }
        dataTask.resume()
    }
}

這是用於解碼和數據 object 結構的“摘要”數據 model 的結構:

import Foundation

struct Summary: 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 調用和 JSON 解碼的結果根據需要使用 ObserveableObject 和 @Published 發布。

在 ContentView 中,我遵循 ObservedObject 規則,只想在 UI 上顯示來自 JSON 數據的數據點,以確認它正在工作:

import SwiftUI
import Foundation
import Combine

struct ContentView: View {

    @ObservedObject var summary = APICall()

    var body: some View {

        Text($summary.date)

        .onAppear {
            self.summary.pullSummary()
        }
    }

    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
}

但是...我在文本顯示行收到這 2 個錯誤,1) Initializer 'init(_:)' requires that 'Binding<Subject>' conform to 'StringProtocol'和 2) Value of type 'ObservedObject<APICall>.Wrapper' has no dynamic member 'date' using the key path from root type 'APICall'

我猜第二個錯誤是問題的根本原因,表明數據沒有正確傳遞到 ContentView 中。

我很感激任何建議。

謝謝。

內部屬性混亂的視圖 model

struct ContentView: View {

    @ObservedObject var viewModel = APICall()

    var body: some View {

        Text(viewModel.summary?.date ?? "Loading...") // << no $ sign !!!

        .onAppear {
            self.viewModel.pullSummary()
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM