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

使用Swift Decodable解码含转义字符与花括号的JSON字符串失败问题求助

解决Swift Decodable解码嵌套转义JSON字符串的问题

首先,咱们先找出你解码失败的根本原因:你在Swift中定义的JSON字符串写法有误,导致生成的JSON本身格式无效,这才是返回nil的核心问题。

问题分析

你用三重引号"""定义多行字符串时,错误地使用了\"来表示JSON里的转义双引号。但在Swift的多行字符串中,\"会被直接解析成一个普通双引号,而非JSON要求的转义双引号\"(也就是JSON字符串里的\+")。最终生成的JSON会变成这样的无效格式:

{
  "orders":[
    {
      "extra":"{"desired_pick_up_time":"ASAP"}" // 这里的双引号未转义,破坏了JSON结构
    }
  ]
}

自然无法被正确解码。


解决方案1:修正JSON字符串,将extra解码为String

先把Swift中的JSON字符串写对:要在JSON里表示转义双引号,需要在Swift多行字符串中写\\"(第一个\是Swift的转义符,用来表示第二个\是JSON的转义符)。

正确的JSON字符串定义:

var json = """
{
  "orders":[
    {
      "extra":"{\\"desired_pick_up_time\\":\\"ASAP\\"}"
    }
  ]
}
"""

或者用普通字符串写法:

var json = "{\"orders\":[{\"extra\":\"{\\\"desired_pick_up_time\\\":\\\"ASAP\\\"}\"}]}"

此时你原来的模型代码完全可以正常工作,建议修正解码代码中的try?(它会吞掉错误,不利于排查问题):

let jsonData = json.data(using: .utf8)!
let decoder = JSONDecoder()
do {
    let welcome = try decoder.decode(Welcome.self, from: jsonData)
    print(welcome) // 现在能正常输出解码结果了
} catch {
    print("解码错误:\(error)")
}

解决方案2:直接将extra解码为结构体(进阶需求)

如果你的目标不是拿到String,而是要解析extra里的desired_pick_up_time值,可以自定义解码逻辑,直接把嵌套的JSON字符串解码为对应模型:

  1. 定义Extra结构体:
struct Extra: Decodable {
    let desiredPickUpTime: String
    
    enum CodingKeys: String, CodingKey {
        case desiredPickUpTime = "desired_pick_up_time"
    }
}
  1. 修改Order结构体,自定义解码逻辑:
struct Order: Decodable {
    let extra: Extra
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        // 第一步:把extra字段解码为String
        let extraString = try container.decode(String.self, forKey: .extra)
        // 第二步:把String转为Data,再解码为Extra
        guard let extraData = extraString.data(using: .utf8) else {
            throw DecodingError.dataCorruptedError(
                forKey: .extra,
                in: container,
                debugDescription: "无法将extra字符串转为Data"
            )
        }
        let innerDecoder = JSONDecoder()
        self.extra = try innerDecoder.decode(Extra.self, from: extraData)
    }
    
    enum CodingKeys: String, CodingKey {
        case extra
    }
}
  1. 解码测试:
let jsonData = json.data(using: .utf8)!
let decoder = JSONDecoder()
do {
    let welcome = try decoder.decode(Welcome.self, from: jsonData)
    print(welcome.orders.first?.extra.desiredPickUpTime) // 直接输出"ASAP"
} catch {
    print("解码错误:\(error)")
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 09:34:08