Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

Kotlin Multiplatform Projectʂ

Slide 6

Slide 6 text

,PUMJO.VMUJQMBUGPSN1SPKFDU • KotlinͰͷΫϩεϓϥοτϑΥʔϜ։ൃ • UI͸ڞ௨ԽͤͣϩδοΫ෦෼ͷΈڞ௨Խ͢Δ • JVM, Native, javascript • ݱ࣌఺Ͱ͸Experimental feature • ུশ͸MPP? KMP?
 https://speakerdeck.com/kpgalligan/kotlin-multiplatform-libraries

Slide 7

Slide 7 text

ϓϥοτϑΥʔϜݻ༗ͷ࣮૷ • 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ͰϦΫΤετͷ಺༰ม͍͑ͨՕॴ ͳͲͰར༻

Slide 8

Slide 8 text

4XJGU͔Βݟͨ"1*ΫϥΠΞϯτ • Kotlin͔ΒframeworkΛग़ྗͰ͖Δ • suspend function͸frameworkʹग़ྗ͞Εͳ͍ suspend fun InhouseClient.login(email: String, password: String): Response { return post(email, password) } • Swift༻ʹDefferedͰฦ͢Α͏ʹ͢Δ fun InhouseClient.loginAsync(email: String, password: String): Deferred> { return GlobalScope.async(coroutineDispatcher) { login(email, password) } }

Slide 9

Slide 9 text

4XJGU͔Β"1*ΫϥΠΞϯτΛ࢖͏ import InhouseClient let deferred = client.loginAsync(email: "[email protected]",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?Λฦ͢ͷͰΩϟετ

Slide 10

Slide 10 text

4XJGU༻ͷϥούʔΛ࡞Δ • ͜ͷ··ͩͱݺͼग़͠ଆ͕ΫϥΠΞϯτͷ࣮૷ͷৄࡉΛ஌͍ͬͯΔඞཁ͕͋Δ • Swift༻ͷϥούʔΛ࡞Δ͜ͱʹͨ͠ • ܕΩϟετΛ୲͏ • FutureͰฦ͢Α͏ʹ͢Δ • ΞϓϦͷ࣮૷ͰSwiftUI࢖͏ͱͷ͜ͱͩͬͨͷͰCombine࢖͍ͬͯ͘ • droidkaigi2019ͷΞϓϦͰRxSwiftͷasSingleʹͯ͠ฦ͍ͯ͠Δͷ͕ࢀߟ ʹͳͬͨ
 https://qiita.com/takahirom/items/4df7bfca17928a40922e

Slide 11

Slide 11 text

'VUVSFΛฦ͢FYUFOTJPOΛ༻ҙ extension Kotlinx_coroutines_coreDeferred { func asFuture(success: Success.Type, error: Fail.Type) -> Future { return Future { 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)) } } )} }

Slide 12

Slide 12 text

'VUVSFΛฦ͢Α͏ʹ͍ͯ͘͠ public func login(email: String, password: String) -> Future { return client .loginAsync(email: email, password: password) .asFuture(success: LoginSuccess.self, error: LoginiFail.self) }               

Slide 13

Slide 13 text

ݺͼग़͠ଆ#FGPSF"GUFS • Before import InhouseClient let deferred = client.loginAsync(email: "[email protected]",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: "[email protected]",password: "password") .sink(receiveValue: { value in doSomething(user: value.user) }, receiveCompletion { completion in handle(completion) })

Slide 14

Slide 14 text

࢖ͬͯ΋Βͬͨ • ࣮ࡍʹ࢖ͬͯ΋Βͬͨͱ͜ΖɺϩάΠϯͷ࣮ ૷͕αΫοͱͰ͖ͨͱ͍͏ϑΟʔυόοΫΛ ΋Β͑ͨ • ϓϩτλΠϓͷ࣮૷ΛՃ଎ͤ͞ΒΕͦ͏

Slide 15

Slide 15 text

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