等待处理请求以显示信息
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-way
而 TextField()
会。
应查找 @State
@ObservedObject
@ObservableObject
和 @Published
的额外阅读和学习,这将帮助您站稳脚跟,更灵敏地使用 SwiftUI。
感谢您的所有回复,但是我设法使用 completionHandler 解决了我的问题。这是对我有帮助的问题和答案的 link:Whosebug question
我想制作一个 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-way
而 TextField()
会。
应查找 @State
@ObservedObject
@ObservableObject
和 @Published
的额外阅读和学习,这将帮助您站稳脚跟,更灵敏地使用 SwiftUI。
感谢您的所有回复,但是我设法使用 completionHandler 解决了我的问题。这是对我有帮助的问题和答案的 link:Whosebug question