You need to enable JavaScript to run this app. SwiftUI 如何从嵌套JSON API获取数据并集成Playground解析逻辑
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI 如何从嵌套JSON API获取数据并集成Playground解析逻辑

嵌套JSON适配SwiftUI数据层的修正实现

当前集成代码的核心问题

  • 网络调用语句被直接写在SwiftUI View的结构体作用域中,值类型的View不支持直接执行顶层函数调用,所有拉取逻辑必须封装在ObservableObject类内部
  • 自定义的Fetcher类没有添加@Published修饰的可观察属性,Body中引用的fetch.tracks为未定义的错误字段,无法触发视图更新
  • 解码逻辑没有绑定嵌套JSON对应的最外层模型,也没有将提取到的视频数组传递给可观察属性完成赋值

完整可运行的修正代码

1. 匹配JSON结构的Codable模型

严格对齐你已在Playground中验证可解析的嵌套层级,不需要额外改动结构:

// 最外层响应模型
struct Welcome: Codable {
    let races: Races
}

// 嵌套的races层级模型
struct Races: Codable {
    let videos: [Video]
}

// 视频模型,补充Identifiable协议支持List渲染
struct Video: Codable, Identifiable {
    let id: Int
    let url: String
    let title: String
}

2. 改造后的ObservableObject数据层

复用你之前适配简单JSON的请求逻辑,仅调整解码的目标类型:

class VideoFetcher: ObservableObject {
    // 用@Published修饰的属性,数据更新时自动驱动视图刷新
    @Published var videos: [Video] = []
    
    init() {
        // 初始化时自动触发数据拉取,和原有简单JSON的流程保持一致
        loadNestedVideos()
    }
    
    private func loadNestedVideos() {
        guard let url = URL(string: "https://你的实际API地址") else {
            print("无效的请求地址")
            return
        }
        
        URLSession.shared.dataTask(with: url) { [weak self] data, response, error in
            // 基础错误处理
            if let error = error {
                print("网络请求失败:\(error.localizedDescription)")
                return
            }
            guard let data = data else {
                print("未接收到返回数据")
                return
            }
            
            do {
                // 关键调整:直接解码最外层的Welcome嵌套模型,而非直接解码Video数组
                let response = try JSONDecoder().decode(Welcome.self, from: data)
                // 切换到主线程,从嵌套结构中提取videos数组完成赋值
                DispatchQueue.main.async {
                    self?.videos = response.races.videos
                }
            } catch {
                print("JSON解析失败:\(error.localizedDescription)")
            }
        }.resume()
    }
}

3. 适配的SwiftUI视图层

完全对齐你之前可运行的视图结构,删除无效的顶层函数调用:

struct VideosView: View {
    @ObservedObject var fetcher = VideoFetcher()
    
    var body: some View {
        List(fetcher.videos) { video in
            VStack(alignment: .leading, spacing: 8) {
                Text(video.title)
                    .font(.headline)
                Text(video.url)
                    .font(.subheadline)
                    .foregroundColor(.secondary)
            }
            .padding(.vertical, 4)
        }
    }
}

关键逻辑说明

  • 整个实现流程和你之前处理简单对象数组JSON的流程没有本质区别,唯一差异是解码时的目标类型:简单JSON直接解码[Video].self,嵌套JSON先解码最外层的嵌套模型,再从层级中取出目标数组赋值即可
  • 不要在View结构体中书写网络请求、JSON解析这类业务逻辑,View仅负责渲染@Published属性传递的数据源
  • 所有对@Published属性的赋值必须在主线程执行,避免UI渲染异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.30 23:27:11