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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:19:34