json - SwiftUI 在 GET 请求后显示 JSON 数据
问题描述
我知道这是典型的并发问题,但我是 Swift 新手,我觉得我已经阅读了所有相关的博客文章。我知道我正在正确获取数据,因为它显示在我的控制台中,但我无法让它显示在我的模拟器中。我相信这是因为我在加载数据之前显示 UI。
在我 100% 获取所有数据后如何显示数据。我将添加控制台的相关代码和屏幕截图。对不起,如果这是一个“基本”问题。
结构
struct Welcome: Decodable, Identifiable {
var id: Int?
var readings: [Reading]?
var include_maintenance_recommendations: Bool?
var pool_volume: Int?
var created_at, updated_at: String?
}
struct Reading: Decodable {
var analyte: String?
var value: String?
}
用户界面
var results = Welcome()
struct ContentView: View {
@State var res = Welcome()
var body: some View {
Text(results.created_at ?? "N/A")
.onAppear(){
fetchResults().getData {(res) in
self.res = res
}
}
}
}
获取函数
class fetchResults{
func getData(completion: @escaping (Welcome) -> ()){
print("Fetch")
let parameters = "{ \"pool_volume\": 10000, \"readings\": [ { \"analyte\": \"fc\", \"value\": 1.6 }, { \"analyte\": \"ph\", \"value\": 7.3 } ]}"
let postData = parameters.data(using: .utf8)
var request = URLRequest(url: URL(string: "https://www.biolabhydra.com/api/v3/water_tests")!,timeoutInterval: Double.infinity)
request.addValue("Basic ***********************", forHTTPHeaderField: "Authorization")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("csrftoken=***********************", forHTTPHeaderField: "Cookie")
request.httpMethod = "POST"
request.httpBody = postData
let task = URLSession.shared.dataTask(with: request) { (data, _, _) in
let resultList = try! JSONDecoder().decode(Welcome.self, from: data!)
print(" ")
print("ID: \(resultList.id ?? 111)")
print("VOLUME: \(resultList.pool_volume ?? 111)")
print("RECOMMENDATIONS: \(resultList.include_maintenance_recommendations ?? true)")
print("CREATD AT: \(resultList.created_at ?? "N/A")")
print("UPDATED AT: \(resultList.updated_at ?? "N/A")")
print("READINGS: \(String(describing: resultList.readings))")
print(" ")
print("SUCCESS: Got data - \(data! )")
}
task.resume()
}
}
解决方案
- 使用局部属性而不是全局变量
struct ContentView: View {
@State var res = Welcome()
var body: some View {
Text(res.created_at ?? "N/A") // << here !!
.onAppear(){
fetchResults().getData {(res) in
self.res = res
}
}
}
}
- 解码数据后添加回调
let task = URLSession.shared.dataTask(with: request) { (data, _, _) in
let result = try! JSONDecoder().decode(Welcome.self, from: data!)
print(" ")
print("ID: \(resultList.id ?? 111)")
print("VOLUME: \(resultList.pool_volume ?? 111)")
print("RECOMMENDATIONS: \(resultList.include_maintenance_recommendations ?? true)")
print("CREATD AT: \(resultList.created_at ?? "N/A")")
print("UPDATED AT: \(resultList.updated_at ?? "N/A")")
print("READINGS: \(String(describing: resultList.readings))")
print(" ")
print("SUCCESS: Got data - \(data! )")
DispatchQueue.main.async {
completion(result) // << here !!
}
}
推荐阅读
- mybatis - Mybatis resultMap中如何使用Multiple collection
- linux - 文件未排序后排序
- java - 从数据库加载 netflix zuul 路由值
- python - Gstreamer、Docker、udpsrc、OpenCV、Python... 不工作
- laravel - Laravel 日志异常
- vba - VBA - 如果单元格值更改,则移动行
- javascript - 使用 sequelize 获取字段中具有唯一值的所有行
- javascript - 检查并匹配文件扩展名
- flutter - Flutter:如何在不使用标签栏视图的情况下使用导航器创建标签栏?
- gitlab - 在 GitLab 中更改导航主题颜色