Avatar
ボイラープレート消せる方向性探りたいですね
2:26 PM
URLをStringとして持つ話、
  • そこを型として明示したい
  • url.flatMap {URL(string: $0)} を都度書きたくない
と思ったけど、👇このアプローチどうですかね /// デコードしたStringと、TypedなURLは纏めて独自型に押し込めるほうがいい struct RobustURL: Codable { let rawValue: String var typed: URL? { return URL(string: rawValue) } func encode(to encoder: Encoder) throws { var container = encoder.singleValueContainer() try container.encode(rawValue) } init(from decoder: Decoder) throws { rawValue = try decoder.singleValueContainer().decode(String.self) } } /// CoreGraphicに依存しない独自型 struct Size: Codable { let width: Double let height: Double } import CoreGraphics extension Size { var asCGSize: CGSize { return CGSize(width: width, height: height) } } struct Fuga: Codable { let url1: RobustURL // 不正なURLが来うることを型として示せる let url2: RobustURL // 不正なURLが来うることを型として示せる let url3: URL // 不正なURLが来ないことを型として示せる let size: Size } let data = """ { "url1": "https://failable.url", "url2": "不正なURL", "url3": "https://ensured.url", "size": { "width": 100, "height": 50 } } """.data(using: .utf8)! let fuga = try! JSONDecoder().decode(Fuga.self, from: data) fuga.url1.typed // https://failable.url fuga.url2.typed // nil fuga.url3 // https://ensured.url fuga.size.asCGSize // {w 100 h 50} let json = try! JSONEncoder().encode(fuga) print(String(data: json, encoding: .utf8)!) // {"size":{"width":100,"height":50},"url3":"https:\/\/ensured.url","url1":"https:\/\/failable.url","url2":"不正なURL"}