Swift中JSONSerialization.jsonObject解析嵌套JSON失效问题
问题分析与解决方案
嘿,这问题我之前踩过坑!你的代码里把JSON强制转换成了[String:String],这就要求所有字段的值必须是字符串类型。但遇到嵌套JSON(比如message是子字典/数组)时,这个强制转换直接就失败了,代码会跳进catch块返回nil。
快速修复:用[String:Any]兼容嵌套结构
先把类型转换改成更灵活的[String:Any],这样就能容纳不同类型的JSON值,之后再安全提取嵌套字段:
URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in guard let data = data, error == nil else { completion(nil) return } do { // 转成通用字典类型,兼容嵌套结构 guard let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String:Any] else { completion(nil) return } // 安全提取error字段 let errorStatus = json["error"] as? String // 处理嵌套的message:先判断它的类型 if let messageDict = json["message"] as? [String:Any] { // 提取子字段,比如messageDict["detail"] as? String print("嵌套的message字典:\(messageDict)") } else if let messageStr = json["message"] as? String { // 兼容原来的字符串类型message print("字符串类型的message:\(messageStr)") } completion(json) } catch { print("JSON解析失败:\(error.localizedDescription)") completion(nil) } }).resume()
更优雅的方案:使用Codable协议(推荐)
如果你的项目经常处理JSON,苹果的Codable协议能让类型更安全、代码更整洁。比如针对嵌套结构定义对应的数据模型:
// 假设message是固定的子字典,定义模型 struct APIResponse: Codable { let error: String let message: MessageDetail? // 兼容message可能为空的情况 } struct MessageDetail: Codable { let detail: String let code: Int // 根据实际嵌套字段添加属性 }
然后用JSONDecoder解析:
URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in guard let data = data, error == nil else { completion(nil) return } do { let decoder = JSONDecoder() let responseModel = try decoder.decode(APIResponse.self, from: data) // 直接使用类型安全的模型属性 print("error状态:\(responseModel.error)") if let message = responseModel.message { print("message详情:\(message.detail),错误码:\(message.code)") } // 如果需要返回字典,可以按需转换,推荐直接用模型 completion(["error": responseModel.error, "message": message]) } catch { print("Codable解析失败:\(error.localizedDescription)") completion(nil) } }).resume()
要是message可能是字符串或字典两种类型,可以自定义一个遵循Codable的枚举来处理这种多类型场景,代码会更健壮。
内容的提问来源于stack exchange,提问作者Te Me
相关产品推荐
相关产品推荐

