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

値オブジェクトのCodable対応

maguhiro
September 06, 2019

 値オブジェクトのCodable対応

iOSDC Japan 2019のルーキーズLT枠で発表した資料です。

maguhiro

September 06, 2019
Tweet

Transcript

  1. J04%$!NHVIJSP
    ஋ΦϒδΣΫτͷ
    $PEBCMFରԠ

    View full-size slide

  2. ࣗݾ঺հ
    ‣ ໨ࠇതོ!NBHVIJSP
    ‣ גࣜձࣾΧΧΫίϜ
    ‣ ৯΂ϩά৯΂ϩά৽نࣄۀ
    ‣ J04ΞϓϦΤϯδχΞ

    View full-size slide

  3. ࠓ೔࿩͢͜ͱ
    4XJGUͰಋೖ͞Εͨ$PEBCMFΛར༻ͯ͠
    ஋ΦϒδΣΫτΛؚΉܕʹ+40/σίʔυ
    ͨ͠ࡍͷରԠํ๏Λ͓࿩͠·͢

    View full-size slide

  4. αϯϓϧίʔυ

    View full-size slide

  5. struct User: Codable {
    let id: Int
    let name: String
    let age: Int
    }
    let json = """
    {
    "id" : 1234,
    "name" : "maguhiro",
    "age" : 34
    }
    """.data(using: .utf8)!
    let user = try! JSONDecoder()
    .decode(User.self, from: json)
    print("\(user.id)") // 1234

    View full-size slide

  6. ໰୊ࣄྫ
    Ϣʔβʔ*%Λ୯७ͳ*OUܕͰఆٛͯ͠͠·
    ͏ͱɺҾ਺ʹϢʔβʔ*%Λ౉ؔ͢਺Ͱ
    ޡͬͯಉ͡*OUܕͰ͋Δଞͷ஋Λ౉ͯ͠͠
    ·͏ڪΕ͕͋Γ·͢

    View full-size slide

  7. class UserRepositoryImpl {
    func find(_ userID: Int) -> User? {
    // Կ͔͠Β͔ΒσʔλΛऔಘͯ͠ฦ٫
    return user
    }
    }
    let userID = 1234
    let photoID = 1000
    let user = UserRepositoryImpl().find(photoID)
    // ↑ޡͬͯࣸਅIDΛҾ਺ʹ౉ͯ͠͠·͍ͬͯΔ

    View full-size slide

  8. ͲͪΒ΋ಉ͡ܕͳͷͰϏϧυ
    ΤϥʔɾϥϯλΠϜΤϥʔʹ
    ͳΒͳ͍

    View full-size slide

  9. Ͳ͏ͳΕ͹

    خ͍͠ʁ

    View full-size slide

  10. ϏϧυΤϥʔʹͳͬͯ͘Ε
    Δͱخ͍͠Ͱ͢ΑͶʁ

    View full-size slide

  11. Ϣʔβʔ*%Λද͢ܕ͕*OUܕͰ
    ͸ͳ͘ɺϢʔβʔ*%Ͱ͋Δࣄ
    Λࣔ͢ಠࣗͷܕͰఆ͍ٛͨ͠

    View full-size slide

  12. ஋ΦϒδΣΫτΛ
    ಋೖ͠Α͏ʂ

    View full-size slide

  13. ஋ΦϒδΣΫτͱ͸ʁ
    υϝΠϯۦಈઃܭ %%%
    ͷઓज़తઃܭͷ
    ཁૉͷҰͭɻಛ௃ͱͯ͠ҎԼͷΑ͏ͳ΋
    ͷ͕͋Δɻ
    ‣ ෆมͰ͋Δ
    ‣ ஋ಉ࢜Ͱൺֱ͕Մೳ
    ‣ ަ׵Մೳ

    View full-size slide

  14. ઌఔͷίʔυʹ

    ద༻ͯ͠ΈΑ͏

    View full-size slide

  15. struct UserID: Codable {
    let value: Int
    init(value: Int) {
    self.value = value
    }
    }
    struct User: Codable {
    let id: UserID
    let name: String
    let age: Int
    }

    View full-size slide

  16. class UserRepositoryImpl {
    func find(_ userID: UserID) -> User? {
    // Կ͔͠Β͔ΒσʔλΛऔಘͯ͠ฦ٫
    return user
    }
    }
    let userID = UserID(value: 1234)
    let photoID = 1000
    let user = UserRepositoryImpl().find(photoID)
    // ↑ޡͬͯࣸਅIDΛҾ਺ʹ౉͢ͱɺҎԼͷΑ͏ͳΤϥʔ͕ൃੜ͢Δ
    // Cannot convert value of type 'Int' to expected
    argument type 'UserID'

    View full-size slide

  17. ޡͬͨར༻ʹ͙͢
    ؾ͚ͮΔͧʂ

    View full-size slide

  18. Ͱ͸ɺαϯϓϧͷ
    +40/σίʔυ
    ͯ͠ΈΑ͏ʂ

    View full-size slide

  19. let json = """
    {
    "id" : 1234,
    "name" : "maguhiro",
    "age" : 34
    }
    """.data(using: .utf8)!
    let user = try! JSONDecoder()
    .decode(User.self, from: json)
    //
    Swift.DecodingError.typeMismatch(Swift.Dictionaryift.String, Any>,
    Swift.DecodingError.Context(codingPath:
    [CodingKeys(stringValue: "id", intValue: nil)],
    debugDescription: "Expected to decode
    Dictionary but found a number
    instead.", underlyingError: nil))

    View full-size slide

  20. Τϥʔ͕ൃੜ

    View full-size slide

  21. ஋ΦϒδΣΫτͱͯ͠6TFS*%
    ܕΛఆٛͨ͠ࣄͰɺσʔλߏ
    ଄ͷ֊૚͕ਂ͘ͳͬͯ͠·ͬ
    ͨͨΊ

    View full-size slide

  22. Ͳ͏͢Ε͹ʁ

    View full-size slide

  23. TJOHMF7BMVF$POUBJOFSΛ࢖͓͏
    %FDPEFS &ODPEFSϓϩτίϧͰఆٛ͞
    Ε͍ͯΔؔ਺
    ΦϑΟγϟϧυΩϡϝϯτʹ͸ҎԼͷΑ
    ͏ʹهࡌ͞Ε͍ͯΔɻ
    l୯ҰͷϓϦϛςΟϒ஋Λอ࣋͢Δͷʹద
    ͨ͠σίʔυɾΤϯίʔυίϯςφz

    View full-size slide

  24. ࢖ͬͯΈΑ͏ʂ

    View full-size slide

  25. ஋ΦϒδΣΫτΛ
    ද͢ϓϩτίϧͷ
    ࡞੒

    View full-size slide

  26. protocol ValueObject: Codable,
    CustomStringConvertible,
    Equatable {
    associatedtype Value: Codable,
    CustomStringConvertible,
    Equatable
    var value: Value { get }
    init(value: Value)
    }

    View full-size slide

  27. extension ValueObject {
    init(from decoder: Decoder) throws {
    let container = try decoder.singleValueContainer()
    let value = try container.decode(Value.self)
    self.init(value: value)
    }
    func encode(to encoder: Encoder) throws {
    var container = encoder.singleValueContainer()
    try container.encode(value)
    }
    var description: String {
    return value.description
    }
    static func == (lhs: Self, rhs: Self) -> Bool {
    return lhs.value == rhs.value
    }
    }

    View full-size slide

  28. 6TFS*%ܕ΁ద༻

    View full-size slide

  29. struct UserID: ValueObject {
    let value: Int
    init(value: Int) {
    self.value = value
    }
    }

    View full-size slide

  30. let json = """
    {
    "id" : 1234,
    "name" : "maguhiro",
    "age" : 34
    }
    """.data(using: .utf8)!
    let user = try! JSONDecoder()
    .decode(User.self, from: json)
    print(“\(user.id)”) // 1234

    View full-size slide

  31. ·ͱΊ
    ‣ ୯Ұͷ஋ΛΤϯίʔυɾσίʔυ͢Δ
    ৔߹ʹ͸ɺTJOHMF7BMVF$POUBJOFSΛ࢖
    ͍·͠ΐ͏ʂ
    ‣ ஋ΦϒδΣΫτͷΤϯίʔυɾσίʔ
    υΛ࣮ݱ͠ޡͬͨར༻Λ๷͝͏ʂ

    View full-size slide

  32. ͝ਗ਼ௌ͋Γ͕ͱ͏
    ͍͟͝·ͨ͠
    IUUQTHJUIVCDPNNBHVIJSP$PEBCMF4VQQPSU'PS7BMVF0CKFDU

    View full-size slide