引き続きWWDC 2017に参加中のかっくん(@fromkk)です。
今朝聴講した What's New in Foundation というセッションで発表されていたSwift 4からFoundationに採用される Codable
プロトコルに感動したので簡単に紹介したいと思います。
定義
プロトコルの定義はこんな感じです。
public protocol Encodable { public func encode(to encoder: Encoder) throws } public protocol Decodable { public init(from decoder: Decoder) throws } public typealias Codable = Decodable & Encodable
前提
この様なデータをダウンロードする事を想定しています。
{ "hello": "world", "key": null, "int": 12345, "double": 9876.543, "url": "http://timers-inc.com/", }
これまで
これまでAPIとの通信をしてモデルを作成する場合、下記の様な記述をする事が多かったのでは無いでしょうか?
struct OldJson { let hello: String let key: String? let int: Int let double: Double let url: URL } let data: Data = ... do { guard let json: [AnyHashable: Any] = try JSONSerialization.jsonObject(with: data, options: []) as? [AnyHashable: Any] else { print("json convert failed") return } guard let hello: String = json["hello"] as? String, let int: Int = json["int"] as? Int, let double: Double = json["double"] as? Double, let urlString: String = json["url"] as? String, let url: URL = URL(string: urlString) else { print("get values failed") return } let oldJson = OldJson(hello: hello, key: json["key"] as? String, int: int, double: double, url: url) print(oldJson) //Success!!!! } catch { print("json convert failed in JSONSerialization", error.localizedDescription) }
とても長ったらしくて毎回書くのは大変ですよね。
なので APIKit
や Himotoki
といったライブラリを利用して共通化する事が多かったかと思います。
Swift 4以降
Swift 4のFoundationから採用される Codable
を利用すると次の様になります。
struct NewJson: Codable { let hello: String let key: String? let int: Int let double: Double let url: URL } let data: Data = ... let decoder: JSONDecoder = JSONDecoder() do { let newJson: NewJson = try decoder.decode(NewJson.self, from: data) print(newJson) //Success!!! } catch { print("json convert failed in JSONDecoder", error.localizedDescription) }
Codable
が勝手にマッピングしてくれるのでとても短くなりました!
ここまで簡素化出来ると他にやるべき事に集中出来る様になりますね!
また、嬉しい機能としてネストも可能です。
struct Json: Codable { let hello: String let url: URL struct Nested: Codable { let hoge: String let fuga: String } let nested: Nested } let str: String = """ { "hello": "world", "url": "http://timers-inc.com/", "nested": { "hoge": "hogehoge", "fuga": "fugafuga" } } """
JSONのキーとモデルのプロパティ名が異なる場合
サーバーサイドではキーをスネークケースで定義していて、クライアント側ではキャメルケースでプロパティ名を定義しているなんて事もありますよね。
そんな時は CodingKey
を利用すれば解決出来ます。
JSONがこういう時、
{ "hello": "world", "snake_case": "snake case string" }
こうする事でSwiftサイドでは camelCase
というプロパティに snake_case
というキー名を適用させる事が出来ます。
struct Json: Codable { let hello: String let camelCase: String private enum CodingKeys: String, CodingKey { case hello case camelCase = "snake_case" } }
まとめ
正式リリースはまだなので変更される可能性はありますが、現時点でもかなり便利な機能ですね。
個人的にはマッピングの処理はかなり面倒なのでここが自動化されるだけでかなりコーディングが捗るなと感じています。
正式リリースが楽しみですね!!
積極採用中!!
子育て家族アプリFamm、カップル専用アプリPairyを運営するTimers inc. では、現在エンジニアを積極採用中! 急成長中のサービスの技術の話を少しでも聞いてみたい方、スタートアップで働きたい方など、是非お気軽にご連絡ください! 採用HP : http://timers-inc.com/engineerings