Ios 如何在json中使用Codable解析数据具有键但值与enum不匹配任何情况下

Ios 如何在json中使用Codable解析数据具有键但值与enum不匹配任何情况下,ios,parsing,swift4,codable,Ios,Parsing,Swift4,Codable,我已经创建了一个模型,如下所示,带有一个性别自定义枚举 enum Gender :String, Codable { case male = "Male" case female = "Female" } class Person : Codable { var name : String? var gender : Gender? convenience init(name : String, gender : Gender) { s

我已经创建了一个模型,如下所示,带有一个性别自定义枚举

enum Gender :String, Codable {
    case male = "Male"
    case female = "Female"
}

class Person : Codable {
    var name : String?
    var gender : Gender?

    convenience init(name : String, gender : Gender) {
        self.init()
        self.name = name
        self.gender = gender
    }

    enum CodingKeys: String, CodingKey {

        case name    = "name"
        case gender  = "gender"

    }
}
下面是来自API的json数据

[
  {
    "name": "name1",
    "gender": "Male"
  },
  {
    "name": "name2",
    "gender": "Male"
  }
]
在响应的成功块中,如果我用下面的代码解析数据,它工作正常

  do {

        let list = try JSONDecoder().decode([Person].self, from: data)

        print("list \(list)")

    }
    catch {
        print("error \(error)")
    }
现在的问题是,在响应api中,如果像“gender”这样的所有小写字母
中都提供了gender:“male”
则解析不起作用,并给出以下错误

error dataCorrupted(Swift.DecodingError.Context(codingPath: 
[_JSONKey(stringValue: "Index 1", intValue: 1), CodingKeys(stringValue:
"gender", intValue: nil)], debugDescription: "Cannot initialize Gender from
 invalid String value male", underlyingError: nil))
我想要下面的任何一个解决方案

  • 解析数据忽略枚举的大小写值
  • 创建对象 性别为零的人,因为这与任何情况都不匹配

还有一件事我不想覆盖编码器和解码器方法,因为我在实际项目中有很多参数。我已经意识到这一点

您可以通过覆盖
个人的
初始化(从解码器:)
来完成此操作

enum Gender :String, Codable {
    case male, female // Note that I removed the uppercase string values 
}

struct Person : Codable {
    var name : String?
    var gender : Gender?

    enum CodingKeys: String, CodingKey {
        case name, gender // No need for string values if they match the enum cases
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        name = try container.decodeIfPresent(String.self, forKey: .name) // decodeIfPresent as name is optional 

        let genderString = try container.decode(String.self, forKey: .gender)
        gender = Gender(rawValue: genderString.lowercased()) // This is why I removed the uppercase String values
    }
}

如果使用
JSONDecoder
填充模型对象,如果不希望使用默认行为,则必须重写解码器方法。另外,您所说的“我的实际项目中有我的参数”是什么意思?Swift枚举区分大小写。你不能解析“男性”,它应该是“男性”。