Skip to content

Instantly share code, notes, and snippets.

@takasek
Last active June 19, 2017 22:15
Show Gist options
  • Save takasek/c74bac87f3480972e44d18d1af13d7a7 to your computer and use it in GitHub Desktop.
Save takasek/c74bac87f3480972e44d18d1af13d7a7 to your computer and use it in GitHub Desktop.
CodingKeyのマッピングを動的に切り替える ref: http://qiita.com/takasek/items/94a8c3ccd7843c84f7fb
/// CodingKeyのマッピングを動的に切り替える
protocol CodingKeyMapper {
static var mapper: [String: S<Self>.CodingKeys] { get }
}
extension CodingKeyMapper {
static var mapper: [String: S<Self>.CodingKeys] { return [:] }
static func key(_ stringValue: String) -> S<Self>.CodingKeys? {
return mapper[stringValue]
}
static func stringValue(_ key: S<Self>.CodingKeys) -> String {
return mapper.first { $0.value == key }?.key ?? String(describing: key)
}
}
///Mapperの実体にはdictを定義するだけ
struct Pattern1: CodingKeyMapper {
static let mapper: [String: S<Pattern1>.CodingKeys] = [
"i_another": .i,
"s_another": .s,
]
}
/// 欠けたkey(👇では .s ) は、String(describing: key) として扱われる
struct Pattern2: CodingKeyMapper {
static let mapper: [String: S<Pattern2>.CodingKeys] = [
"i_yet_another": .i,
]
}
/// key名の変更がないなら何も書く必要がない
struct Pattern0: CodingKeyMapper {}
struct S<Mapper: CodingKeyMapper>: Codable {
let i: Int
let s: String
enum CodingKeys: CodingKey {
case i
case s
init?(stringValue: String) {
guard let k = Mapper.key(stringValue) else { return nil }
self = k
}
var stringValue: String {
return Mapper.stringValue(self)
}
}
}
import Foundation
let data = """
{
"i": 1,
"s": "デフォルトのsですよ",
"i_another": 10,
"s_another": "別のsですよ",
"i_yet_another": 999,
}
""".data(using: .utf8)!
let decoder: JSONDecoder = JSONDecoder()
let s0 = try! decoder.decode(S<Pattern0>.self, from: data)
let s1 = try! decoder.decode(S<Pattern1>.self, from: data)
let s2 = try! decoder.decode(S<Pattern2>.self, from: data)
dump([s0, s1, s2])
▿ 3 elements
▿ __lldb_expr_26.S<__lldb_expr_26.Pattern0>
- i: 1
- s: "デフォルトのsですよ"
▿ __lldb_expr_26.S<__lldb_expr_26.Pattern1>
- i: 10
- s: "別のsですよ"
▿ __lldb_expr_26.S<__lldb_expr_26.Pattern2>
- i: 999
- s: "デフォルトのsですよ"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment