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

Kotlin Multiplatform Projectで社内用APIクライアントを作る

k-tomoyasu
November 11, 2019

Kotlin Multiplatform Projectで社内用APIクライアントを作る

potatochips #66 で発表
Kotlin Multiplatform Projectで社内用APIクライアントを作る

k-tomoyasu

November 11, 2019
Tweet

More Decks by k-tomoyasu

Other Decks in Programming

Transcript

  1. Kotlin Multiplatform ProjectͰ ࣾ಺APIΫϥΠΞϯτΛ࡞Δ potatotips #66 2019/11/11

  2. ࣗݾ঺հ • ໊લ: ༑҆ߤଠ(@fusuma0325) • ࢓ࣄ: ωΠςΟϒΞϓϦͷ։ൃ • ొࢁͨ͠ΓήʔϜͨ͠Γ •

    potatotipsॳࢀՃ
  3. ࠓ೔ͷ࿩ - Kotlin Multiplatform ProjectͰࣾ಺APIͷ Android, iOS༻ΫϥΠΞϯτΛ࡞ͬͨ - Swift༻ͷϥούʔΛ࡞ͬͨ

  4. ࡞ΔʹࢸΔ·Ͱ • ࣾ಺ͷAPIͰAndroid, iOSΞϓϦΛ࡞ΔϓϩδΣΫ τΛ༗ࢤͰ࢝Ίͨ • ೝূΛ͸͡Ίͱͯ͠APIͷ࢓༷͕݁ߏ΍΍͍͜͠ • ͜͜ΛΫϦΞ͢Δͱ։ൃʹ͸ͣΈΛ͚ͭΒΕͦ͏ •

    APIΫϥΠΞϯτΛ༻ҙ͍͚ͨ͠ͲAndroid, iOS྆ ํ࡞Δͷ͸΍΍͠ΜͲ͍
  5. Kotlin Multiplatform Projectʂ

  6. ,PUMJO.VMUJQMBUGPSN1SPKFDU • KotlinͰͷΫϩεϓϥοτϑΥʔϜ։ൃ • UI͸ڞ௨ԽͤͣϩδοΫ෦෼ͷΈڞ௨Խ͢Δ • JVM, Native, javascript •

    ݱ࣌఺Ͱ͸Experimental feature • ུশ͸MPP? KMP?
 https://speakerdeck.com/kpgalligan/kotlin-multiplatform-libraries
  7. ϓϥοτϑΥʔϜݻ༗ͷ࣮૷ • expect / actual (≒ abstract / concrete) ͰϓϥοτϑΥʔϜݻ༗ͷ࣮૷͕Մೳ

    • expectͰϓϥοτϑΥʔϜ͝ͱͷ࣮૷Λཁٻ internal expect val platform : String • actualͰϓϥοτϑΥʔϜ͝ͱʹ࣮૷ • Android internal actual val platform = “ANDROID” • iOS internal actual val platform = "IOS" • ࠓճͷAPIΫϥΠΞϯτͰ͸iOS / AndroidͰϦΫΤετͷ಺༰ม͍͑ͨՕॴ ͳͲͰར༻
  8. 4XJGU͔Βݟͨ"1*ΫϥΠΞϯτ • Kotlin͔ΒframeworkΛग़ྗͰ͖Δ • suspend function͸frameworkʹग़ྗ͞Εͳ͍ suspend fun InhouseClient.login(email: String,

    password: String): Response<LoginSuccess, LoginFail> { return post<LoginSuccess, LoginFail>(email, password) } • Swift༻ʹDefferedͰฦ͢Α͏ʹ͢Δ fun InhouseClient.loginAsync(email: String, password: String): Deferred<Response<LoginSuccess, LoginFail>> { return GlobalScope.async(coroutineDispatcher) { login(email, password) } }
  9. 4XJGU͔Β"1*ΫϥΠΞϯτΛ࢖͏ import InhouseClient let deferred = client.loginAsync(email: "hogehoge@example.com",password:"password") deferred.invokeOnCompletion(cause in

    let response = deferred.getCompleted() if let result = response as? Response.Success { if let success = result as! LoginSuccess { doSomething(user: success.user) } } }) • APIΫϥΠΞϯτΛimport • Deffered͔ΒgetCompleted()Ͱ݁ՌΛऔΓग़͢ • getCompleted()͕Any?Λฦ͢ͷͰΩϟετ
  10. 4XJGU༻ͷϥούʔΛ࡞Δ • ͜ͷ··ͩͱݺͼग़͠ଆ͕ΫϥΠΞϯτͷ࣮૷ͷৄࡉΛ஌͍ͬͯΔඞཁ͕͋Δ • Swift༻ͷϥούʔΛ࡞Δ͜ͱʹͨ͠ • ܕΩϟετΛ୲͏ • Future<Output, Failure>Ͱฦ͢Α͏ʹ͢Δ

    • ΞϓϦͷ࣮૷ͰSwiftUI࢖͏ͱͷ͜ͱͩͬͨͷͰCombine࢖͍ͬͯ͘ • droidkaigi2019ͷΞϓϦͰRxSwiftͷasSingleʹͯ͠ฦ͍ͯ͠Δͷ͕ࢀߟ ʹͳͬͨ
 https://qiita.com/takahirom/items/4df7bfca17928a40922e
  11. 'VUVSFΛฦ͢FYUFOTJPOΛ༻ҙ extension Kotlinx_coroutines_coreDeferred { func asFuture<Success, Fail>(success: Success.Type, error: Fail.Type)

    -> Future<Success, Fail> { return Future<Success, Fail> { promise in self.invokeOnCompletion( cause in if let cause = cause { promise(.failure(Fail(cause))) return } if let completion = self.getCompleted() as? Response.Success { let result = completion as! Success.Type promise(.success(result)) } } )} }
  12. 'VUVSFΛฦ͢Α͏ʹ͍ͯ͘͠ public func login(email: String, password: String) -> Future<LoginSuccess, LoginFail>

    { return client .loginAsync(email: email, password: password) .asFuture(success: LoginSuccess.self, error: LoginiFail.self) }               
  13. ݺͼग़͠ଆ#FGPSF"GUFS • Before import InhouseClient let deferred = client.loginAsync(email: "hogehoge@example.com",password:"password")

    deferred.invokeOnCompletion(cause in let response = deferred.getCompleted() if let result = response as? Response.Success { if let success = result as! LoginSuccess { doSomething(user: success.user) } } }) • After import InhouseClientSwifty client.login(email: "hogehoge@example.com",password: "password") .sink(receiveValue: { value in doSomething(user: value.user) }, receiveCompletion { completion in handle(completion) })
  14. ࢖ͬͯ΋Βͬͨ • ࣮ࡍʹ࢖ͬͯ΋Βͬͨͱ͜ΖɺϩάΠϯͷ࣮ ૷͕αΫοͱͰ͖ͨͱ͍͏ϑΟʔυόοΫΛ ΋Β͑ͨ • ϓϩτλΠϓͷ࣮૷ΛՃ଎ͤ͞ΒΕͦ͏

  15. ·ͱΊ • Kotlin Multiplatform ProjectͰࣾ಺༻ͷAPIΫϥΠ ΞϯτΛ࡞Δͱḿͬͨ • ڞ௨ԽͷൣғΛߜͬͯͨͷ͕ྑ͔͔ͬͨ΋ • Swift༻ʹ͸؆୯ͳϥούʔΛ࡞Δͱ࢖͍΍͘͢

    ͳͬͨ • ܕͷΩϟετɾFutureͰฦ͢