TL;DR
空文字列or不正なURL表現を許容するCodable変換のためのPropertyWrapperを作った.
課題
サーバーなど送られてきたJSONをCodableで変換するとき,以下のようなJsonが送られてくると失敗してしまう.このJSONは,avatarが未設定の場合などを想定している.以下のstructに渡してやれば動きそうだが,実際にはURLに空文字列(""
)を渡すとエラーが起きてしまう.
{
"id": "12345userid",
"name": "Yamada Taro",
"avatarUrl": ""
}
struct User: Codable {
var id: String
var name: String
var avatarUrl: URL?
}
解決
以下のようなPropertyWrapperを作った.これによって不正なURLを許容するための専用Decoderを作る必要がなくなる.
@propertyWrapper
struct AllowEmptyURL: Codable {
var wrappedValue: URL?
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
wrappedValue = try? container.decode(URL.self)
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(wrappedValue)
}
}
struct User: Codable {
var id: String
var name: String
@AllowEmptyURL
var avatarUrl: URL?
}
解説
decodeする際にはPropertyWrapperのinitが呼ばれる.その際にtry?
にしてやることで例外発生時にはnil
が渡されるようになっている.encodeメソッドはdecodeするだけなら不要だが,書いておかないとencodeしたくなったときにおかしくなるので注意が必要.