Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Get started with Kotlin Multiplatform Mobile
Search
Hiroyuki Kusu
March 05, 2021
Programming
600
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Get started with Kotlin Multiplatform Mobile
Yumemi.apk #3 (
https://yumemi.connpass.com/event/202135/
) の資料
Hiroyuki Kusu
March 05, 2021
More Decks by Hiroyuki Kusu
See All by Hiroyuki Kusu
スクラムガイドを踏まえた実践についての考え方
hkusu
0
47
モノレポのプルリクエストに最近、導入したもの
hkusu
2
610
GitHub composite actions
hkusu
2
480
Android の静的解析における SARIF ファイルの活用
hkusu
0
5.8k
CI_でライブラリのバージョンの変化をレポートする.pdf
hkusu
0
440
Maestro を GitHub Actions で動かす 〜Android編〜
hkusu
1
1.8k
Android の CI(GitHub Actions)の改善で、最近やったこと
hkusu
0
760
Tauri Mobile で生成される Android のコードを見てみる
hkusu
0
1.6k
Custom GitHub Actions を作って Organization 内で共有する
hkusu
1
620
Other Decks in Programming
See All in Programming
AIが生成したコードは読むべきか?抽象化設計とコードの品質保証 / abstraction-design-and-quality
minodriven
16
8.6k
PumaからFalconに移行したRailsアプリケーションでの実践
falcon8823
0
350
まずはコードより業務と向き合う:テーブル解体のためにPdMを呼んだ話
sakawe_ee
0
150
Kotlinの15年とServer-Side Kotlin
n_takehata
1
200
[JA] Domain Modeling with Vanilla Rails: 「操作」から再考するRailsの設計論
yasaichi
4
1.8k
Groovy as a human and AI friendly programming language
paulk
0
180
TanStack Vue Query と Pinia Colada から学ぶ非同期状態の型設計
aoshi
0
610
Railsバージョンを4倍にした話
optim
0
930
Lambda durable functionsでHuman in the Loopを楽に…楽に……
har1101
2
280
Spec-driven Development with AI
simas
PRO
0
2.2k
Performance Optimization With LLMs
xleitix
0
240
FactoryBotをやめればRSpecは速くなるのか?
yuta_onishi_97
0
1.5k
Featured
See All Featured
We Have a Design System, Now What?
morganepeng
55
8.4k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Writing Fast Ruby
sferik
630
63k
The Invisible Side of Design
smashingmag
301
52k
Evolving SEO for Evolving Search Engines
ryanjones
0
350
sira's awesome portfolio website redesign presentation
elsirapls
0
490
XXLCSS - How to scale CSS and keep your sanity
sugarenia
250
1.3M
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
660
Odyssey Design
rkendrick25
PRO
2
920
Joys of Absence: A Defence of Solitary Play
codingconduct
1
570
What the history of the web can teach us about the future of AI
inesmontani
PRO
2
790
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
670
Transcript
Get started with Kotlin Multiplatform Mobile 2021.03.05 YUMEMI.apk #3 Hiroyuki
Kusu ( @hkusu_ )
About me
https://blog.jetbrains.com/ja/kotlin/2020/09/kotlin-multiplatform-mobile-goes-alpha-ja/
https://kotlinlang.org/docs/mobile/home.html KMM ͷυΩϡϝϯτ
Android Studio ༻ͷϓϥάΠϯ
৽ن KMM ϓϩδΣΫτ࡞༻ͷςϯϓϨʔτ
KMMϓϩδΣΫτͷܗ͕࡞͞ΕΔ
https://github.com/hkusu/KmmSampleApp ؆୯ͳαϯϓϧΛ࡞ͬͯΈͨ
6TF$BTF 3FQPTJUPSZ "QJ %BUB$MBTT "DUJWJUZ 7JFX.PEFM BOESPJE"QQ JPT"QQ ※ ࠓճݕূͰ͖͍ͯ·ͤΜ
(JU)VC"1* TIBSFE
• ಈ࡞֬ೝͨ͠ϩʔΧϧڥ • Android Studio 4.1.2 • Android Studio Plugin
• Kotlin: 1.4.31-release-Studio4.1-1 • Kotlin Multiplatform Mobile: 0.2.0-release-65-Studio4.1 • ϏϧυπʔϧϥΠϒϥϦͷόʔδϣϯ GitHub ͷίʔυͷํΛΈ͍ͯͩ͘͞
plugins { // ... id("kotlinx-serialization") } kotlin { // ...
sourceSets { val commonMain by getting { dependencies { // ... implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.1.0") implementation("io.ktor:ktor-client-core:1.5.2") implementation("io.ktor:ktor-client-serialization:1.5.2") } } // ... val androidMain by getting { dependencies { // ... implementation("io.ktor:ktor-client-android:1.5.2") } } // ... val iosMain by getting { dependencies { implementation("io.ktor:ktor-client-ios:1.5.2") } } // ... } } build.gradle.kts shared Coroutines + serialization + Ktor ͷಋೖ ※ ਖ਼֬ͳઃఆ GitHub ͷίʔυͷํΛݟ͍ͯͩ͘͞
plugins { // ... id("kotlin-kapt") } kotlin { // ...
sourceSets { // ... val androidMain by getting { dependencies { // ... implementation("com.google.dagger:hilt-android:2.31.2-alpha") // javax.annotation.Generated ͕ݟ͔ͭΒͳ͍Τϥʔ͕ग़ΔͷͰ.. compileOnly("javax.annotation:javax.annotation-api:1.3.2") } } // ... } } // ref: https://www.reddit.com/r/Kotlin/comments/ack2r6/problem_using_kapt_in_a_multiplatform_project/ dependencies { "kapt"("com.google.dagger:hilt-android-compiler:2.31.2-alpha") } build.gradle.kts shared ※ ਖ਼֬ͳઃఆ GitHub ͷίʔυͷํΛݟ͍ͯͩ͘͞ Dagger Hilt ͷಋೖ(Androidͷํʹ͚ͩ)
buildscript { repositories { gradlePluginPortal() jcenter() google() mavenCentral() } dependencies
{ classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.30") classpath("com.android.tools.build:gradle:4.1.2") classpath("org.jetbrains.kotlin:kotlin-serialization:1.4.30") classpath("com.google.dagger:hilt-android-gradle-plugin:2.31.2-alpha") } } allprojects { repositories { google() jcenter() mavenCentral() } } ϓϩδΣΫτϧʔτͷ build.gradle.kts
shared/commonMain Ktor ෦Ҏ֎ී௨ͷ Kotlin + Coroutines ͷίʔυͳͷͰ Ktor ෦͚ͩҎ߱Ͱઆ໌ ڞ௨ιʔε෦
internal object Libs { internal val httpClient: HttpClient by lazy
{ HttpClient { install(JsonFeature) { serializer = KotlinxSerializer(json = Json { ignoreUnknownKeys = true }) } } } } shared/commonMain Ktor ͷ HTTP ΫϥΠΞϯτͷੜͱ Kotlin serialization ͷઃఆ Android/iOS Ͱڞ௨ͷઃఆͰOK
internal class GitHubApi(private val httpClient: HttpClient) { suspend fun getUserList():
List<GitHubUserResponse> { return httpClient.get("${BASE_URL}/users") } companion object { private const val BASE_URL = "https://api.github.com" } } shared/commonMain suspending function ʹରԠ APIͷఆٛ
@Module @InstallIn(SingletonComponent::class) internal object Module { @Provides fun provideGitHubApi(): GitHubApi
{ return GitHubApi(Libs.httpClient) } @Provides @Singleton fun provideUserRepository(gitHubApi: GitHubApi): UserRepository { return UserRepositoryImpl(gitHubApi) } @Provides fun provideGetUserUseCase(userRepository: UserRepository): GetUserUseCase { return GetUserUseCase(userRepository) } } shared/androidMain Dagger Hilt ͷϞδϡʔϧ ※ commonMain ʹ Dagger ແ͘ίϯετϥΫλΠϯδΣΫγϣϯͰ͖ͳ͍ͷͰ ͜͜ͰΠϯελϯεੜํ๏Λఆٛ (SharedͷதͷOSผ࣮)
plugins { id("com.android.application") kotlin("android") id("kotlin-kapt") id("dagger.hilt.android.plugin") } dependencies { implementation(project(":shared"))
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2") implementation("androidx.appcompat:appcompat:1.2.0") implementation("androidx.core:core-ktx:1.3.2") implementation("androidx.activity:activity-ktx:1.2.0") implementation("androidx.fragment:fragment-ktx:1.3.0") implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.0") implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.3.0") implementation("androidx.constraintlayout:constraintlayout:2.0.4") implementation("com.google.android.material:material:1.3.0") implementation("com.google.dagger:hilt-android:2.31.2-alpha") kapt("com.google.dagger:hilt-android-compiler:2.31.2-alpha") } android { compileSdkVersion(29) // ... build.gradle.kts androidApp ͓ͳ͡ΈͷϥΠϒϥϦୡ
plugins { id("com.android.application") kotlin("android") id("kotlin-kapt") id("dagger.hilt.android.plugin") } dependencies { implementation(project(":shared"))
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2") implementation("androidx.appcompat:appcompat:1.2.0") implementation("androidx.core:core-ktx:1.3.2") implementation("androidx.activity:activity-ktx:1.2.0") implementation("androidx.fragment:fragment-ktx:1.3.0") implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.0") implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.3.0") implementation("androidx.constraintlayout:constraintlayout:2.0.4") implementation("com.google.android.material:material:1.3.0") implementation("com.google.dagger:hilt-android:2.31.2-alpha") kapt("com.google.dagger:hilt-android-compiler:2.31.2-alpha") } android { compileSdkVersion(29) // ... build.gradle.kts androidApp Dagger Hilt
@HiltViewModel class MainViewModel @Inject constructor(getUser: GetUserUseCase) : ViewModel() { private
val _userList: MutableLiveData<List<User>> = MutableLiveData() val userList = _userList as LiveData<List<User>> init { viewModelScope.launch { _userList.value = getUser() } } } ViewModel androidApp Dagger Hilt
@HiltViewModel class MainViewModel @Inject constructor(getUser: GetUserUseCase) : ViewModel() { private
val _userList: MutableLiveData<List<User>> = MutableLiveData() val userList = _userList as LiveData<List<User>> init { viewModelScope.launch { _userList.value = getUser() } } } ViewModel androidApp shared ʹஔ͍ͨ UseCase Λ inject
• Android ෦ʹؔͯ͠ී௨ʹ࡞Εͦ͏ • Android ͔ΒݟΕී௨ͷϚϧνϞδϡʔϧߏ • ڞ௨ιʔε෦ʹ͍ͭͯ.. • ϚϧνϓϥοτϑΥʔϜରԠͷϥΠϒϥϦΛར༻͢Δඞཁ͕͋Δ
• ͜͜Λ iOS ͚ʹͲ͏ఏڙ͍͔͕ͯ͘͠ϙΠϯτʹͳΓͦ͏ • iOS ͚ʹ DI ͢ΔͳΒ KOIN Kodein Λར༻ͨ͠ํ͕Αͦ͞͏
Thank you ! @hkusu_