web-dev-qa-db-ja.com

Codableオブジェクトの非Codableオプションプロパティを無視する

Codableプロトコルに準拠している場合、非Codableクラスのオプションプロパティを簡単にスキップできません

Ride構造体では、driverプロパティのencodingおよびdecodingをスキップし、デコード時に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)
}

オプションのプロパティをスキップする別の方法はありますか?これは、モデルが大きいほど簡単になります。

11
KIO

driverデフォルト値を指定してみてください。たとえば、これはコンパイル済みなしエラーXcode 9.

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これは、コンパイラーがデフォルトで行うことでもあるためです;)

23
Paulo Mattos