iOSDC Japan 2019にて、@maguhiro による素晴らしいLTがありました。
値オブジェクトへのCodable対応 by maguhiro | トーク | iOSDC Japan 2019 #iosdc - fortee.jp
この投稿では、筆者が同様の実装をする場合によくやる方法を、別解として紹介します。
実装
struct User: Codable {
var id: UserID
var name: String
}
struct UserID: Codable, RawRepresentable {
var rawValue: Int
init(rawValue: Int) {
self.rawValue = rawValue
}
}
do {
let json = """
{
"id": 1,
"name": "administrator"
}
""".data(using: .utf8)!
let user = try JSONDecoder().decode(User.self, from: json)
print("id: \(user.id.rawValue), name: \(user.name)") // id: 1, name: administrator
} catch {
print(error)
}
do {
let user = User(id: .init(rawValue: 2), name: "member")
let json = try JSONEncoder().encode(user)
print(String(data: json, encoding: .utf8)!) // {"id":2,"name":"member"}
} catch {
print(error)
}
解説
RawRepresentable
のRawValue
が特定の型だった場合、Encodable
, Decodable
のデフォルト実装がされています。
これを利用することで、init(from:)
, encode(to:)
を自分で実装する必要が無くなります。
デフォルト実装の内容は @maguhiro のスライドのものと同様ですね。