You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JSONResponseView显示空对象求助:已接收有效JSON却无法展示

问题原因与解决方案

问题原因

  1. 后台线程更新UI状态
    URLSession的dataTask闭包运行在后台线程,你直接在闭包里更新responseJSON和showingResponseView这些SwiftUI状态属性,而SwiftUI要求所有状态更新必须在主线程执行。虽然控制台能打印出正确数据,但状态更新没有同步到UI线程,导致Sheet拿到的还是旧的空数据。

  2. Sheet预渲染导致数据不同步
    使用sheet(isPresented:)时,Sheet的内容视图(JSONResponseView)会在showingResponseView变为true之前就被预初始化,此时responseJSON还是初始的空值。即使之后更新了responseJSON,由于Sheet已经完成初始化,不会自动响应参数变化,所以展示的还是空对象。

正确实现方式

步骤1:确保状态更新在主线程

在dataTask闭包中,所有更新UI状态的操作必须通过DispatchQueue.main.async切换到主线程执行。

步骤2:使用sheet(item:)替代sheet(isPresented:)

通过sheet(item:)绑定一个可选的响应数据对象,当这个对象有值时自动弹出Sheet,并且每次对象更新时,Sheet会重新初始化视图,确保拿到最新的数据。

修改后的代码示例

首先定义一个遵循Identifiable的响应类型(sheet(item:)要求绑定对象必须实现该协议):

struct JSONResponse: Identifiable {
    let id = UUID()
    let data: [String: Any]
}

修改原视图的状态属性:

// 替换原来的responseJSON和showingResponseView
@State private var response: JSONResponse?

更新sendRequest方法:

func sendRequest(with jsonData: Data) {
    guard let url = URL(string: "http://localhost:7071/api") else {
        print("Invalid URL")
        return
    }
    
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.httpBody = jsonData
    
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        if let error = error {
            print("Error:", error)
            return
        }
        
        guard let data = data else {
            print("No data received")
            return
        }
        
        if let jsonString = String(data: data, encoding: .utf8) {
            print("-->Raw JSON Data Received:", jsonString)
        }
        
        do {
            let result = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] ?? ["Test": "OK"]
            print(" Report:", result)
            
            // 切换到主线程更新状态
            DispatchQueue.main.async {
                self.response = JSONResponse(data: result)
            }
        } catch {
            print("Error parsing JSON:", error)
        }
    }
    
    task.resume()
    
    if let jsonString = String(data: jsonData, encoding: .utf8) {
        print("Generated JSON Payload Outgoing:\n", jsonString)
    }
}

修改Sheet的调用逻辑:

var body: some View {
    Form {
        PersonDetailsSection(name: $person1Name, title: "Enter Person 1's Details")
        
        Button {
            if let jsonData = JSONPayloadGenerator.createPayload(person1Name: person1Name) {
                sendRequest(with: jsonData)
            }
        } label: {
            Text("Send Request")
        }
    }
    .navigationBarTitle("My App")
    .padding()
    // 使用sheet(item:)绑定响应数据,自动触发视图展示
    .sheet(item: $response) { response in
        JSONResponseView(jsonResponse: response.data)
            .onAppear {
                print("Presenting JSONResponseView")
            }
    }
}

内容的提问来源于stack exchange,提问作者Vampavi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 05:07:45