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

SwiftUI应用从MongoDB获取用户数据时JSON解码失败求助

问题分析与解决方案

你遇到的解码错误(NetworkError error 3对应decodingError),核心原因是JSON字段与Swift结构体属性名不匹配,再加上后台线程更新UI的潜在问题,具体修复步骤如下:

1. 修正结构体的JSON键映射

你的JSON数据里用户ID字段是_id,但Swift结构体里定义的是id,JSONDecoder默认会按完全匹配的键名解码,直接导致失败。给Account结构体添加CodingKeys枚举手动映射字段即可解决:

struct Account: Decodable, Identifiable {
    var id: String
    var username: String
    var password: String
    var __v: Int
    
    // 映射JSON字段与结构体属性
    private enum CodingKeys: String, CodingKey {
        case id = "_id"
        case username, password, __v
    }
}

如果你的API有大量蛇形命名字段,也可以用JSONDecoder的自动转换策略替代手动映射:

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let accounts = try decoder.decode([Account].self, from: data)

2. 优化错误日志,精准定位问题

当前代码只返回笼统的decodingError,看不到具体失败原因,建议在catch分支打印错误详情:

do {
    let accounts = try JSONDecoder().decode([Account].self, from: data)
    completion(.success(accounts))
} catch {
    print("解码失败详情:\(error)") // 打印具体错误,比如哪个字段不匹配
    completion(.failure(.decodingError))
}

3. 切回主线程更新UI

URLSession.dataTask的回调运行在后台线程,直接修改@State变量usernames可能导致UI更新异常,需要把赋值操作切回主线程:

case.success(let accounts):
    DispatchQueue.main.async {
        self.usernames = accounts
        print("usernames: \(usernames)")
    }

额外安全建议

从安全角度考虑,后端接口不应返回用户密码明文,建议修改Node.js接口,只返回_id和username字段,避免敏感数据泄露。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 22:37:05