忽略Codable对象中的非Codable可选属性

时间:2017-10-18 15:51:51

标签: json swift swift4 codable decodable

当符合Codable协议时,我不能轻易跳过非Codable类的可选属性

Ride结构中,我们要跳过driver属性的编码解码,并在解码时保留nil

  struct Ride: Codable {

    public var number: String
    public var passenger: Passenger? // Codable conforming
    public var driver: Driver?       // NSObject subclass, doesn't conform to Codable

    enum CodingKeys: String, CodingKey {
      case number
      case passenger
    }
  }

在这种情况下,我收到编译错误

  

类型'驱动程序'不符合协议'可解码'

到目前为止,我唯一提供的解决方案是通过提供以下方法对手动进行编码和解码:

public init(from decoder: Decoder) throws {
    let values = try decoder.container(keyedBy: CodingKeys.self)
    number = try? values.decode(String.self, forKey: .number)
    passenger = try? values.decode(Passenger.self, forKey: .passenger)
}

public func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(number, forKey: .number)
    try container.encode(passenger, forKey: .passenger)
}

是否有其他方法可以跳过可选属性?对于更大的模型,这将更容易。

1 个答案:

答案 0 :(得分:18)

尝试为driver提供默认值。例如,在 Xcode 9.0 上编译没有错误:

struct Ride: Codable {
    public var number: String
    public var passenger: Passenger? 
    public var driver: Driver? = nil

    private enum CodingKeys: String, CodingKey {
        case number
        case passenger
    }
}

struct Passenger: Codable { /* ... */ }

class Driver: NSObject { /* ... */ }

快速测试:

let rideJSON =
"""
{
    "number": "123"
}
""".data(using: .utf8)!

let ride = try! JSONDecoder().decode(Ride.self, from: rideJSON)
print(ride) /* Ride(number: "123", passenger: nil, driver: nil) */

顺便说一句,我使用了private CodingKeys因为这也是编译器默认执行的操作;)