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

Swift JSON转换报错:无法将__NSArrayM转为NSDictionary求助

解决Swift JSON转换错误:__NSArrayM转NSDictionary失败

嘿,我来帮你捋清楚这个问题~你遇到的这个错误,核心原因其实是API返回的JSON顶层结构是数组,但你的代码把它当成了字典来处理——哪怕你没直接写NSArray/NSDictionary,Swift和Objective-C的桥接机制会自动把JSON类型映射成对应的Foundation类型,所以才会报这个错。

具体排查和解决步骤:

  • 先确认API返回的JSON结构
    虽然你说在C#里运行正常,但很可能这个API返回的是数组格式的JSON(比如 [{"id": 1, "title": "xxx"}, {"id":2, ...}]),而不是你预期的字典格式(比如 {"todos": [...], "status": "success"})。你可以先把API返回的原始数据转成字符串打印出来验证:

    // 假设你已经拿到了从API获取的data
    if let rawJsonStr = String(data: data, encoding: .utf8) {
        print("API原始返回:\(rawJsonStr)")
    }
    

    看输出就能明确顶层是数组还是字典了。

  • 检查你的解析代码
    你提到代码里只有print(todo),那todo的类型肯定是被你声明成了字典类型(比如[String: Any]),或者在解析时做了强制类型转换。比如可能你写了类似这样的代码:

    let todo = try JSONSerialization.jsonObject(with: data) as! [String: Any]
    print(todo)
    

    这里的as! [String: Any]是强制转成字典,但实际返回的是数组,所以就会触发那个类型转换错误。

  • 修正解析逻辑
    如果确认返回的是数组,就把解析代码改成对应数组类型的转换:

    do {
        if let todoArray = try JSONSerialization.jsonObject(with: data) as? [[String: Any]] {
            print("拿到的todo数组:\(todoArray)")
            // 要是需要处理单个元素,就遍历数组
            for singleTodo in todoArray {
                print("单个todo内容:\(singleTodo)")
            }
        }
    } catch {
        print("解析错误:\(error)")
    }
    

    用as?做可选绑定,还能避免强制转换崩溃,更安全。

补充说明

C#的JSON序列化/反序列化对类型的容忍度可能比Swift高,比如直接返回列表时,C#可以自动转成对应的集合类型,但Swift是强类型语言,必须严格匹配JSON结构和解析的类型,所以才会出现你说的“其他API正常、C#里正常,但Swift报错”的情况——问题不在API本身,而是你对它返回的结构预期错了~

内容的提问来源于stack exchange,提问作者Jim C.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:48:04