Skip to content

Instantly share code, notes, and snippets.

@takasek
Last active October 27, 2017 03:32
Show Gist options
  • Save takasek/36af17cca297ef73f8bcc1463f9e50c1 to your computer and use it in GitHub Desktop.
Save takasek/36af17cca297ef73f8bcc1463f9e50c1 to your computer and use it in GitHub Desktop.
あと、今日DiscordのSwiftチャンネルでの本題「URL?型に空文字を与えるとdecodeでエラーになるのどうするか」、色々方法出たけど、俺的にはここが結論。 #CodePiece
/// 空文字などのURLが作れない文字列でもデコードに成功する型を用意
struct RobustURL: Codable, RawRepresentable {
let rawValue: String
var typed: URL? {
return URL(string: rawValue)
}
}
/// CGSizeと互換性があるのは
/// {"width": Number, "height": Number} じゃなくて
/// [Number, Number] ☠️なので無理に使わず独自型へデコード
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"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment