如何在SwiftUI的ForEach中遍历API返回的嵌套字典数据
解决SwiftUI中遍历API返回字典数据的问题
首先看你的代码和模型,核心问题是**responses是单个DataClass对象,不是数组**,ForEach仅支持遍历集合类型(比如数组),直接用它遍历单个对象会报错。下面分两种场景给出解决方案:
场景1:API返回单个用户数据(当前模型结构)
如果API返回的是单条用户信息,不需要用ForEach,直接安全解包后展示字段即可:
修改ContentView代码
struct UserData: View { @StateObject var api = userData() var body: some View { VStack(alignment: .leading, spacing: 8) { // 安全解包避免空值崩溃 if let user = api.responses { Text("姓名:\(user.firstName ?? "未设置")") Text("邮箱:\(user.email ?? "未设置")") Text("手机号:\(user.countrycode ?? "")\(user.phoneNumber ?? "")") // 其他字段同理,用??处理可选值 } else { Text("加载中...") } } .onAppear { api.loadData() } } }
场景2:API返回用户数组(需调整模型)
如果API返回的是多用户列表,先修改模型结构,将data字段改为数组类型:
修改模型结构体
struct userDataModel: Codable { let status: Bool? let message: String? // 将data改为DataClass数组 let data: [DataClass] } struct DataClass: Codable { // 注意:[Any?]无法被Codable直接解码,建议替换为具体类型或自定义解码 let id, phoneNumber, email, countrycode: String? let loginType: String? let otp: Int? // 示例:若bookingInfo是字典数组,改为[[String: Any]]后需自定义解码 let bookingInfo, cancellationInfo: [[String: Any]] let token: String? let isHost: Bool? let wishList: [String] let contacts, review: [[String: Any]] let createdAt, updatedAt: String? let v: Int? let dob, firstName, lastName: String? let isOnline: Bool? let lastSeen: String? let isExperience: Bool? }
调整网络类的Published变量
@Published var records: userDataModel? // 对应数组类型 @Published var responses: [DataClass]?
修改ContentView遍历数组
struct UserData: View { @StateObject var api = userData() var body: some View { List { // 安全解包数组,用唯一id作为遍历标识 ForEach(api.responses ?? [], id: \.id) { user in VStack(alignment: .leading, spacing: 4) { Text("姓名:\(user.firstName ?? "未设置")") Text("邮箱:\(user.email ?? "未设置")") Divider() } } } .onAppear { api.loadData() } } }
额外注意事项
- 禁止使用强制解包(
!),用if let或guard let做安全解包,避免空值崩溃。 - 模型中的
[Any?]类型无法被Codable自动解码,需替换为具体的Codable结构体,或改为[[String: Any]]并实现自定义解码逻辑。 ForEach的id参数优先使用对象的唯一标识(比如id字段),比\.self更可靠,尤其是对象有更新时。
内容的提问来源于stack exchange,提问作者user19179931
相关产品推荐
相关产品推荐

