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.

