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

SwiftUI 2环境下如何正确解析JSON并将Group数组渲染为列表展示

问题解决指南

1. 现有代码的问题点

  • 你将Group和Product两个独立的JSON结构揉在同一个Post模型里,完全不符合JSON的层级关系,会直接导致解析失败
  • 你提供的JSON片段存在语法缺失,修正后的完整结构为外层包含groups和goods两个数组字段
  • 编码键枚举里的分组字段写为group,但实际JSON对应的键是groups,拼写不匹配
  • 解析时使用try!强制解包,一旦字段缺失会直接触发崩溃,不建议在生产代码中使用

2. 正确的Decodable模型定义

// 对应JSON根节点的外层结构
struct ResponseModel: Decodable {
    let groups: [GroupItem]
    let goods: [ProductItem]
}

// groups数组的单个元素结构
struct GroupItem: Decodable {
    let id: String
    let name: String
    let img: String
    // 如果字段可能缺失可以改为可选类型,比如 let img: String?
}

// goods数组的单个元素结构
struct ProductItem: Decodable {
    let id: Int
    let name: String
    let text: String
    let price: Int
    let unit: String
    let index: String
    let img: String
    let groups: [String] // 对应你需要提取的分组数组
}

3. JSON解析工具方法

func loadLocalJSON() -> ResponseModel? {
    // 替换成你自己的JSON文件名
    guard let fileURL = Bundle.main.url(forResource: "data", withExtension: "json") else {
        print("未找到目标JSON文件")
        return nil
    }
    do {
        let jsonData = try Data(contentsOf: fileURL)
        let decodedResult = try JSONDecoder().decode(ResponseModel.self, from: jsonData)
        return decodedResult
    } catch {
        print("JSON解析失败,错误信息:\(error)")
        return nil
    }
}

4. SwiftUI 2 列表展示实现

展示顶层groups数组的列表

struct GroupListPage: View {
    let groupList: [GroupItem]
    
    var body: some View {
        List(groupList, id: \.id) { item in
            HStack(spacing: 12) {
                // 如果图片是网络链接,可用AsyncImage加载;本地图片直接用Image加载即可
                AsyncImage(url: URL(string: item.img)) { image in
                    image.resizable()
                } placeholder: {
                    Color.gray.frame(width: 40, height: 40)
                }
                .frame(width: 40, height: 40)
                .cornerRadius(4)
                
                Text(item.name)
            }
        }
        .navigationTitle("全部分组")
    }
}

展示单个商品关联的groups数组

struct ProductGroupListPage: View {
    // 传入商品对应的groups数组
    let productGroups: [String]
    
    var body: some View {
        List(productGroups, id: \.self) { groupName in
            Text(groupName)
        }
        .navigationTitle("商品关联分组")
    }
}

页面调用示例

struct MainPage: View {
    @State private var responseData: ResponseModel?
    
    var body: some View {
        NavigationView {
            if let data = responseData {
                // 展示全部分组列表
                GroupListPage(groupList: data.groups)
                // 如果要展示某个商品的分组,替换为 ProductGroupListPage(productGroups: data.goods[0].groups)
            } else {
                ProgressView("加载数据中")
                    .onAppear {
                        responseData = loadLocalJSON()
                    }
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者Евгений Штин

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 23:09:01