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

SwiftUI 视图展示前数据未更新、跳转新页面数据为空问题

SwiftUI网络请求数据未同步到跳转视图修复方案

核心问题原因

你的代码存在两个核心逻辑错误导致数据加载晚于视图渲染:

  • finished回调执行时机错误:当前finished()写在网络请求发起之前,点击按钮后直接触发页面跳转,完全没有等待网络数据返回
  • 状态更新线程错误:URLSession的网络回调默认在后台线程执行,SwiftUI要求所有状态变量更新必须在主线程执行,否则不会触发视图刷新
  • 额外需注意:传递数据用的lP/t/m变量必须声明为@State(当前视图内定义)或@Published(存放在ObservableObject视图模型中)的响应式属性,否则数据更新无法通知视图

修复步骤

1. 修正loadData方法

需调整回调位置、增加逃逸闭包标记、切换主线程更新数据:

// 给finished闭包加@escaping标记,因为要在异步回调中执行
func loadData(dT : String, finished: @escaping () -> Void) {
    let urlString = "https://myurl" + dT
    
    guard let url = URL(string: urlString) else {
        return
    }
    
    let task = URLSession.shared.dataTask(with: url, completionHandler: { [weak self] data, _, error in
        guard let data = data, error == nil else {
            return
        }
        
        var result: Simulation?
        do {
            result = try JSONDecoder().decode(Simulation.self, from: data)
        }
        catch {
            print("Failed : \(error)")
        }
        
        guard let final = result else {
            return
        }
        
        // 这里保留你原有逻辑,注意你原代码中`t = f`应该是取返回结果的对应字段,这里修正为从final取
        let t = final.f
        
        // 切换到主线程更新状态变量,再执行回调
        DispatchQueue.main.async {
            for ts in t {
                self?.lP.append(ts.lP!)
                self?.m.append(ts.m!)
                self?.t.append(ts.t!)
            }
            // 数据更新完成后再触发跳转
            finished()
        }
    })
    // 启动网络任务
    task.resume()
}

2. 可选优化

可在按钮点击后增加加载状态禁用按钮,避免用户重复点击触发多次请求和页面跳转。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 11:45:03