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

APIクライアントをCodableで置き換えた話

 APIクライアントをCodableで置き換えた話

potatotips #50

Keisuke Kobayashi

April 19, 2018
Tweet

More Decks by Keisuke Kobayashi

Other Decks in Programming

Transcript

  1. API
    クライアントをCodable

    置き換えた話
    Keisuke Kobayashi / @kobakei
    potatotips #50

    View Slide

  2. About Me
    Keisuke Kobayashi
    Twitter: @kobakei122
    GitHub, Qiita: @Kobakei
    Kyash, Inc
    Android Engineer -> iOS Engineer ->
    Engineering Manager

    View Slide

  3. 会社のブログ
    Kyash iOS
    アプリの大規模リファクタリングの話
    http://blog.kyash.co/entry/2018/03/20/150238
    ちょっとだけバズった

    View Slide

  4. Codable
    Swift 4 ~
    JSON
    のシリアライズとデシリアライズの仕組み

    View Slide

  5. Sample
    struct Hoge: Codable {
    let foo: String
    let bar: String?
    }
    let data: Data = ...
    let decoder: JSONDecoder = JSONDecoder()
    do {
    let hoge: Hoge = try decoder.decode(Hoge.self, from: data)
    print(newJson) //Success!!!
    } catch {
    ...
    }

    View Slide

  6. 実際のAPI
    をCodable
    に置き換
    えた

    View Slide

  7. CodableAlamo re
    https://github.com/Otbivnoe/CodableAlamo re
    responseDecodableObject
    が追加される

    View Slide

  8. CodableAlamo re
    response.result.value
    で変換後のオブジェクト取得
    Alamofire.request(url)
    .responseDecodableObject { (res: DataResponse) in
    let hoge = res.result.value
    print(hoge)
    }

    View Slide

  9. enum
    enum Brand: String, Decodable {
    case visa = "visa"
    case mastercard = "mastercard"
    }

    View Slide

  10. Nested Object
    そのまま使える
    struct Author: Decodable {
    let name: String
    }
    struct Book: Decodable {
    let author: Author //
    別のDecodable
    な構造体
    }

    View Slide

  11. JSON
    のキーとstruct
    のキーが
    違う
    例) default
    はSwift
    の予約語だからisDefault
    にした

    {
    "default": true
    }

    View Slide

  12. JSON
    のキーとstruct
    のキーが
    違う
    CodingKey
    を作る
    struct Hoge: Decodable {
    let isDefault: Bool
    private enum CodingKeys: String, CodingKey {
    case isDefault = "default"
    }
    }

    View Slide

  13. 日付の文字列をDate
    に変換す

    dateDecodingStrategy
    にフォーマッタをセット
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSxxx"
    dateFormatter.locale = Locale(identifier: "en_US_POSIX")
    // ↑
    これがないと12
    時間表記モードでパースできない
    let decoder = JSONDecoder()
    decoder.dateDecodingStrategy = .formatted(dateFormatter)
    let newJson: Hoge = try decoder.decode(Hoge.self, from: data)

    View Slide

  14. JSON
    とstruct
    の構造が違う
    同じキーでも型が違うJSON
    (辛い)
    [
    {
    "type": "user",
    "target": {
    "firstName": "Keisuke",
    "lastName": "Kobayashi"
    }
    },
    {
    "type": "store",
    "target": {
    "name": "Amazon"
    }
    }
    ]

    View Slide

  15. JSON
    とstruct
    の構造が違う
    それぞれのstruct
    を別のフィールドにする
    public struct Transaction: Decodable {
    let type: String
    let user: User?
    let store: Store?
    private enum CodingKeys: String, CodingKey {
    case type
    case target // JSON
    のキー"target"
    に対応
    }
    ...

    View Slide

  16. JSON
    とstruct
    の構造が違う
    init
    を自分で実装する(めんどくさい)
    decode
    のキーはいずれもtarget
    を使う
    ...
    public init(from decoder: Decoder) throws {
    let values = try decoder.container(keyedBy: CodingKeys.
    type = try values.decode(String.self, forKey: .type)
    if type == "user" {
    user = try values.decode(User.self, forKey: .target)
    } else if type == "store" {
    store = try values.decode(Store.self, forKey: .target)
    }
    }
    }

    View Slide

  17. まとめ
    Codable
    いいぞ
    Alamo re
    使ってるならCodableAlamo re
    いいぞ
    つらいJSON
    でもinit
    で自分でデコードすればなん
    とかなるけどつらいぞ

    View Slide

  18. Try! Codable

    View Slide