Ios “convertFromSnakeCase”战略没有';不能在Swift中使用自定义“编码键”

Ios “convertFromSnakeCase”战略没有';不能在Swift中使用自定义“编码键”,ios,swift,codable,jsondecoder,Ios,Swift,Codable,Jsondecoder,我尝试使用Swift 4.1的新特性在JSON解码期间将snake-case转换为camelCase 以下是: 我需要提供自定义的CodingKeys,因为convertFromSnakeCase策略无法推断首字母缩略词或首字母大写(例如studentID),但我希望convertFromSnakeCase策略仍然适用于testScore。但是,解码器抛出错误(“没有与密钥编码密钥相关的值”),似乎我不能同时使用convertFromSnakeCase策略和自定义CodingKeys。我遗漏了什

我尝试使用Swift 4.1的新特性在JSON解码期间将snake-case转换为camelCase

以下是:


我需要提供自定义的
CodingKeys
,因为
convertFromSnakeCase
策略无法推断首字母缩略词或首字母大写(例如
studentID
),但我希望
convertFromSnakeCase
策略仍然适用于
testScore
。但是,解码器抛出错误(“没有与密钥编码密钥相关的值”),似乎我不能同时使用
convertFromSnakeCase
策略和自定义
CodingKeys
。我遗漏了什么吗?

JsoneCoder(和
JsoneCoder
)的关键策略应用于有效负载中的所有密钥,包括您为其提供自定义编码密钥的密钥。解码时,JSON密钥将首先使用给定的密钥策略进行映射,然后解码器将参考解码的给定类型的
CodingKeys

在您的情况下,JSON中的
student\u id
键将通过
.convertFromSnakeCase
映射到
studentId
。转换的精确算法为:

  • 将下划线后面的每个单词大写

  • 删除所有不在字符串开头或结尾的下划线

  • 将单词组合成一个字符串

  • 以下示例显示了应用此策略的结果:

    fee\u fi\u fou fum

    转换为:
    feeFiFoFum

    feeFiFoFum

    转换为:
    feeFiFoFum

    base\u uri

    转换为:
    baseUri

    因此,您需要更新您的
    编码键
    ,以匹配此项:

    internal struct StudentInfo: Decodable, Equatable {
      internal let studentID: String
      internal let name: String
      internal let testScore: String
    
      private enum CodingKeys: String, CodingKey {
        case studentID = "studentId"
        case name
        case testScore
      }
    }
    

    您需要
    case studentID=“studentID”
    (比较)–解码器在查询编码键之前应用键策略,因此它将
    “学生id”
    转换为
    “studentID”
    。谢谢@Hamish!真管用@当我有时间的时候,罗布会这样做(如果没有其他人在同一时间发布答案,那就是)哇!非常感谢您指出转换的顺序!非常有用的答案,虽然结果是我不打算使用
    keyDecodingStrategy
    ,因为它使代码的可读性大大降低。非常好的答案
    internal struct StudentInfo: Decodable, Equatable {
      internal let studentID: String
      internal let name: String
      internal let testScore: String
    
      private enum CodingKeys: String, CodingKey {
        case studentID = "studentId"
        case name
        case testScore
      }
    }