我很难将 json 响应下载到我的数据模型中并在代码中访问它

im having difficulty getting downloaded json response into my data model and accessing it in code

我有以下代码,我在其中尝试将汇率下载到我的应用程序中以用于货币转换。 数据提取似乎工作正常,json 解码模型也是如此,但我无法通过 Rates 变量

获取数据
import SwiftUI
struct ExchangeRates: Codable {
    var conversionRates: [String: Double]?
    
    init(conversionRates:[String:Double]) {
        
        self.conversionRates = conversionRates
    }
    enum CodingKeys: String, CodingKey {
        case conversionRates = "conversion_rates"
    }
}

class DownloadingData:ObservableObject{
    
    @Published var Rates:ExchangeRates = ExchangeRates.init(conversionRates: ["test" : 0])
    
    init() {
        datatask()
    }
    
    func datatask() {
        guard let url = URL(string: "https://v6.exchangerate-api.com/v6/********************/latest/GBP") else {return}
        URLSession.shared.dataTask(with: url){(data,response,error) in
            
            guard let data = data else {
                print("no data")
                return
            }
            guard error == nil else {
                print("error :\(String(describing: error))")
                return
            }
            guard let response = response as? HTTPURLResponse else {
                print("invalid response")
                return
            }
            guard response.statusCode >= 200 && response.statusCode < 300 else {
                print("status code should be 2xx, but is \(response.statusCode)")
                return
            }
            guard let rates = try? JSONDecoder().decode(ExchangeRates.self, from: data) else {return}
            print(rates) **// this works and prints out data**
            DispatchQueue.main.async {
                [weak self] in
                self?.Rates = rates
                print(self?.Rates) **// this works and prints out the data**
            }
            print(self.Rates) **// this doesnt print out anything**
        }.resume()
        print(Rates) **// this doesnt print out anything**
    }
}

我似乎无法将数据输入到 Rates 变量中 请任何指导

谢谢

这里是控制台输出的示例:

ExchangeRates(conversionRates: Optional(["test": 0.0])) 可选(test3.ExchangeRates(转换率:可选([“BZD”:2.7002,“PHP”:68.7948,“PGK”:4.725,“BND”:1.8176,“HNL”:32.8885,“TND” :3.7553,“BDT”:115.2218,“SBD”:10.6866,“NIO”:47.4824,“XDR”:0.963,“IDR”:19213.9064,“XCD”:3.6453,“CAD”:1.7152,“UGX”:4778.6135 ,])

声明 rates – 请以小写字母开头 – 作为空字典

@Published var rates = [String:Double]()

在结构中删除 init 方法并声明字典也是非可选的

struct ExchangeRates: Decodable {
    let conversionRates: [String: Double]
    
    enum CodingKeys: String, CodingKey {
        case conversionRates = "conversion_rates"
    }
}

DispatchQueue 闭包中将 conversionRates 的值赋给 rates

DispatchQueue.main.async { // no weak self needed
    self.rates = rates.conversionRates
}

在视图中枚举字典rates

你可以试试这个,使用你的 ExchangeRates 结构:

class DownloadingData: ObservableObject{
    @Published var rates = ExchangeRates(conversionRates: ["test" : 0])
    
    init() {
        datatask()
    }
    
    func datatask() {
        guard let url = URL(string: "https://v6.exchangerate-api.com/v6/********************/latest/GBP") else {return}
        URLSession.shared.dataTask(with: url){(data,response,error) in
            
            guard let data = data else {
                print("no data")
                return
            }
            guard error == nil else {
                print("error :\(error)")
                return
            }
            guard let response = response as? HTTPURLResponse else {
                print("invalid response")
                return
            }
            guard response.statusCode >= 200 && response.statusCode < 300 else {
                print("status code should be 2xx, but is \(response.statusCode)")
                return
            }
            guard let exRates = try? JSONDecoder().decode(ExchangeRates.self, from: data) else {return}
            print(exRates)
            DispatchQueue.main.async {
                self.rates = exRates   // <--- here
                print(self.rates)     // <--- here
            }
            // print(self.rates) // <--- NEVER here
        }.resume()
    }
}

               

EDIT-1:完成关闭:

class DownloadingData: ObservableObject{
    @Published var rates = ExchangeRates(conversionRates: ["test" : 0])
    
    init() {
        datatask() { isDone in
            print(self.rates) // <--- here OK
        }
    }
    
    func datatask(completion: @escaping(Bool) -> ()) {   // <--- here 
        guard let url = URL(string: "https://v6.exchangerate-api.com/v6/********************/latest/GBP") else {return}
        URLSession.shared.dataTask(with: url){(data,response,error) in
            
            guard let data = data else {
                print("no data")
                return
            }
            guard error == nil else {
                print("error :\(error)")
                return
            }
            guard let response = response as? HTTPURLResponse else {
                print("invalid response")
                return
            }
            guard response.statusCode >= 200 && response.statusCode < 300 else {
                print("status code should be 2xx, but is \(response.statusCode)")
                return
            }
            guard let exRates = try? JSONDecoder().decode(ExchangeRates.self, from: data) else {return}
            print(exRates)   // <--- here OK
            DispatchQueue.main.async {
                self.rates = exRates
                print(self.rates)     // <--- here OK
                completion(true)      // <--- here return completion
            }
        }.resume()
    }
}