等待处理请求以显示信息

Wait for request to be precessed for displaying information

我想制作一个 Swift (5.4.6) 应用程序来显示有关密码的信息。为此,我需要调用一个服务器来获取我想要显示的信息。但是我的应用程序不等待数据被处理,所以我得到一个错误,想要显示一个 nil。

这是我调用服务器的代码:

        
        var cryptos = Cryptos(cryptos: nil)
        
        let url = URL(string: urlString)
        let session = URLSession.shared
        let dataTask = session.dataTask(with: url!) {(data, response, error) in
            if error == nil && data != nil {
                let decoder = JSONDecoder()
                do {
                    cryptos = try decoder.decode(Cryptos.self, from: data!)
                    print(cryptos.cryptos![6].name)
                }
                catch {
                    print("Impossible de convertir les données reçues")
                }
            }
        }
            dataTask.resume()
        return cryptos
    }

这是我要将 json 解码为的结构:

struct Crypto: Codable {
    let name: String
    let symbol: String
    let price: Float
    let totalSupply: Float
    let marketCap: Float
    let change24h: Float
}

struct Cryptos: Codable {
    let cryptos: [Crypto]?
}

最后是我认为的代码:


var lesCryptos = Cryptos()

struct CryptoList: View {
    var body: some View {
        HStack {
            NavigationView {
            }
        }
        .onAppear(perform: getAllCryptosInfos)
    }
    
}

func getAllCryptosInfos() {
    lesCryptos = Worker().getAllCryptosInfos()
    print(lesCryptos.cryptos![7].name)
}

打印名字时出现错误("lesCryptos.cryptos!" is nil)

这也是我得到的 JSON 的示例:

{
  "cryptos": [
    {
      "name":"Bitcoin",
      "symbol":"BTC",
      "price":36301.41347043701,
      "totalSupply":18728856,
      "marketCap":679883945484.275,
      "change24h":0.36443243
    },
    {
      "name":"Ethereum",
      "symbol":"ETH",
      "price":2784.5450982190573,
      "totalSupply":116189845.499,"marketCap":323535864747.07007,
      "change24h":3.46116544
    }
  ]
}

首先,将您的 struct 转换为 class 并设置默认值,这样就不会有 nil 值导致崩溃。

class Crypto: Codable {
    let name: String
    let symbol: String
    let price: Float
    let totalSupply: Float
    let marketCap: Float
    let change24h: Float

    init() {
        name = ""
        symbol = ""
        price = 0.0
        totalSupply = 0.0
        marketCap = 0.0
        change24h: 0.0
    }
}

在我的示例中,请注意 init() 构造函数不接受任何值。这允许我创建一个对象 Crypto() 而无需传递任何值。这意味着我的对象将具有这些默认值,这对您的情况很有用,因为您正在从 nil 值崩溃。

struct ExampleView: View {
     @State var someCrypto = Crypto()

     var body: some View {
         Text("\(someCrypto.name)"
              .onAppear(
                   someCrypto.name = "Example"
              )
     }
}

在这个例子中,我为我的 Crypto 对象使用我的默认构造函数。这确保我的视图可以显示 someCrypto.name 给出的名称 ""。然后我使用 onAppear 来模拟从 API 中获取数据。您会注意到视图会自动更新。这是因为 @State 对象本质上告诉视图监听任何变化,而这些变化是 two-way。虽然在这种情况下 Text() 实际上不会使用它 two-wayTextField() 会。

应查找 @State @ObservedObject @ObservableObject@Published 的额外阅读和学习,这将帮助您站稳脚跟,更灵敏地使用 SwiftUI。

感谢您的所有回复,但是我设法使用 completionHandler 解决了我的问题。这是对我有帮助的问题和答案的 link:Whosebug question