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

Swift中如何在Codable中使用"/"和"%"特殊字符?

解决Swift Codable处理特殊字段名的问题

没问题,这个场景在Swift开发里太常见了,完全可以轻松解决!核心就是利用Codable体系里的**CodingKeys枚举**来做字段名映射,把那些不符合Swift命名规范的API字段(比如带"/"、"%"的),映射成你代码里合法的属性名。

方法一:手动定义CodingKeys(最可靠、推荐)

这是最常用的方案,适合所有特殊字段场景,不管字段名有没有规律。举个具体的例子:

假设API返回的JSON结构是这样的:

{
  "d/a": "some value",
  "test%": "another value"
}

你可以这样定义Codable结构体:

struct ApiResponse: Codable {
    // 用符合Swift规范的属性名
    let daValue: String
    let testPercent: String
    
    // 定义CodingKeys枚举,关联API原始字段名
    enum CodingKeys: String, CodingKey {
        case daValue = "d/a"
        case testPercent = "test%"
    }
}

解析的时候和平时一样使用JSONDecoder就行:

let decoder = JSONDecoder()
do {
    let response = try decoder.decode(ApiResponse.self, from: jsonData)
    print(response.daValue) // 输出"some value"
} catch {
    print("解析错误: \(error)")
}

原理很简单:CodingKeys枚举的rawValue对应API里的原始字段名,枚举case对应你代码里的属性名,Codable会自动完成两者的映射,不管是解码(JSON转结构体)还是编码(结构体转JSON)都能正常工作。

方法二:自定义Key解码策略(适合有规律的批量字段)

如果API里的特殊字段有统一的规律(比如都是带"/"、"%"这类符号),你也可以通过JSONDecoder的keyDecodingStrategy来批量处理,不用逐个写CodingKeys。

比如我们可以把"/"直接去掉,把"%"替换成"Percent",再转成小驼峰命名:

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .custom { codingPath in
    // 获取当前字段的原始名称
    guard let lastKey = codingPath.last else {
        return AnyCodingKey(stringValue: "")
    }
    var keyString = lastKey.stringValue
    
    // 替换特殊字符
    keyString = keyString.replacingOccurrences(of: "/", with: "")
    keyString = keyString.replacingOccurrences(of: "%", with: "Percent")
    
    // 转成小驼峰(可选,根据你的命名习惯调整)
    let components = keyString.components(separatedBy: CharacterSet.alphanumerics.inverted)
    let camelCase = components.enumerated().map { index, component in
        index == 0 ? component.lowercased() : component.capitalized
    }.joined()
    
    return AnyCodingKey(stringValue: camelCase)
}

// 需要一个自定义的CodingKey实现
struct AnyCodingKey: CodingKey {
    var stringValue: String
    var intValue: Int?
    
    init(stringValue: String) {
        self.stringValue = stringValue
    }
    
    init?(intValue: Int) {
        self.intValue = intValue
        self.stringValue = "\(intValue)"
    }
}

这样处理后,"d/a"会被映射成"da","test%"会被映射成"testPercent",你结构体里直接用这些合法属性名就行,不用写CodingKeys。不过这种方式更适合字段名有统一规律的场景,如果字段名乱七八糟没规律,还是手动写CodingKeys更稳妥。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:54:59