Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Advanced Codable

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest. →
Avatar for hmhm hmhm
April 23, 2018
31

Advanced Codable

Codableの使い方

Avatar for hmhm

hmhm

April 23, 2018

Transcript

  1. Codableとは Codableとは public typealias Codable = Decodable & Encodable ▸

    型エイリアス ▸ 右辺を左辺の名前として定義する 2
  2. struct User: Codable { let id: Int let name: String

    let address: String } let data = """ { "id":0, "name": "name", "address": "address" } """.data(using: .utf8)! 4 準備 Codableとは
  3. do { let user = try JSONDecoder().decode(User.self, from: data) }

    catch { } Decodable(JSON -> 構造体) Codableとは 5
  4. do { let user = try JSONDecoder().decode(User.self, from: data) let

    data = try JSONEncoder().encode(user) let json = String(data: data, encoding: .utf8)! } catch { } Encodable(構造体 -> JSON) Codableとは 6
  5. do { let user = try JSONDecoder().decode(User.self, from: data) let

    data = try JSONEncoder().encode(user) } catch { } Data型が基本 8 Codableを使って保存
  6. 保存 Codableを使って保存 9 func save(key: String) { do { let

    data = try JSONEncoder().encode(self) UserDefaults.standard.set(data, forKey: key) } catch let error { print(error) } }
  7. 読み込み 10 Codableを使って保存 static func load(key: String) -> Self? {

    guard let data = UserDefaults.standard.data(forKey: key) else { return nil } do { return try JSONDecoder().decode(Self.self, from: data) } catch let error { print(error) return nil } }
  8. Protocolを作成 protocol Saveable: Codable { func save(key: String) static func

    load(key: String) -> Self? } 11 Codableを使って保存
  9. Protocolを作成 extension Saveable { func save(key: String) { do {

    let data = try JSONEncoder().encode(self) UserDefaults.standard.set(data, forKey: key) } catch let error { print(error) } } static func load(key: String) -> Self? { guard let data = UserDefaults.standard.data(forKey: key) else { return nil } do { return try JSONDecoder().decode(Self.self, from: data) } catch let error { print(error) return nil } } } 12 Codableを使って保存
  10. Protocolを適⽤ struct User: Saveable { let id: Int let name:

    String let address: String } let key = "user" let user = User(id: 0, name: "name", address: "address") user.save(key: key) let user_ = User.load(key: key) 13 Codableを使って保存
  11. struct User{ let id: Int let name: String let address:

    String } let dictionary: [String: Any] = ["id": 0, "name": "name", "address": "address"] 構造体 <-> 辞書型 Codableを使って辞書型を構造体へ 15
  12. 辞書型 -> 構造体 16 static func decode(dictionary:[String: Any]) -> Self?

    { do { let data = try JSONSerialization.data(withJSONObject: dictionary, options: []) return try JSONDecoder().decode(Self.self, from: data) } catch let error { print(error) return nil } } Codableを使って辞書型を構造体へ
  13. 構造体 -> 辞書型 17 func encode() -> [String: Any]? {

    do { let data = try JSONEncoder().encode(self) return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] } catch let error { print(error) return nil } } Codableを使って辞書型を構造体へ
  14. protocol Dictionaryable: Codable { func encode() -> [String: Any]? static

    func decode(dictionary:[String: Any]) -> Self? } Protocolを作成 18 Codableを使って辞書型を構造体へ
  15. extension Dictionaryable { func encode() -> [String: Any]? { do

    { let data = try JSONEncoder().encode(self) return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] } catch let error { print(error) return nil } } static func decode(dictionary:[String: Any]) -> Self? { do { let data = try JSONSerialization.data(withJSONObject: dictionary, options: []) return try JSONDecoder().decode(Self.self, from: data) } catch let error { print(error) return nil } } } Protocolを作成 19 Codableを使って辞書型を構造体へ
  16. struct User: Dictionaryable { let id: Int let name: String

    let address: String } let dictionary: [String: Any] = ["id": 0, "name": "name", "address": "address"] let user = User.decode(dictionary: dictionary) let user_ = User(id: 0, name: "name", address: "address") let dictionary_ = user_.encode() Protocolを適⽤ 20 Codableを使って辞書型を構造体へ
  17. 感想 ▸ 簡単にJSON <-> 構造体 <-> 辞書の変換が可能 ▸ 構造体のプロパティの型を意識しなくて良い ▸

    idはInt型、nameはString型だが変換時に特に意識してい ない ▸ KeyChainにtokenを保存するときにも使⽤可能 22 Codableを使ってみて
  18. struct User: Codable { let id: Int let name: String

    let address: String } let data = """ { "user_id":0, "user_name": "name", "mail-address": "address" } """.data(using: .utf8)! keyが違う・表せない 25 おまけ
  19. struct User: Codable { let id: Int let name: String

    let address: String enum CodingKeys: String, CodingKey { case id = "user_id" case name = "user_name" case address = "mail-address" } } CodingKey機能 26 おまけ
  20. struct User: Codable { let id: Int } let data

    = "{"user_id":0}".data(using: .utf8)! do { let user = try JSONDecoder().decode(User.self, from: data) } catch let error { print(error) // keyNotFound } Error 27 おまけ
  21. struct User: Codable { let id: Int? } let data

    = "{"user_id":0}".data(using: .utf8)! do { let user = try JSONDecoder().decode(User.self, from: data) } catch let error { print(error) } Error 28 おまけ
  22. struct User: Codable { let id: Int } let data

    = "{"id":"id"}".data(using: .utf8)! do { let user = try JSONDecoder().decode(User.self, from: data) } catch let error { print(error) // typeMismatch } Error 29 おまけ