Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Get started with Kotlin Multiplatform Mobile
Search
Hiroyuki Kusu
March 05, 2021
Programming
0
510
Get started with Kotlin Multiplatform Mobile
Yumemi.apk #3 (
https://yumemi.connpass.com/event/202135/
) の資料
Hiroyuki Kusu
March 05, 2021
Tweet
Share
More Decks by Hiroyuki Kusu
See All by Hiroyuki Kusu
モノレポのプルリクエストに最近、導入したもの
hkusu
2
470
GitHub composite actions
hkusu
2
330
Android の静的解析における SARIF ファイルの活用
hkusu
0
4.9k
CI_でライブラリのバージョンの変化をレポートする.pdf
hkusu
0
330
Maestro を GitHub Actions で動かす 〜Android編〜
hkusu
1
1.4k
Android の CI(GitHub Actions)の改善で、最近やったこと
hkusu
0
590
Tauri Mobile で生成される Android のコードを見てみる
hkusu
0
1.3k
Custom GitHub Actions を作って Organization 内で共有する
hkusu
1
510
GitHub Actions でユニットテストの結果をレポートする
hkusu
0
3.4k
Other Decks in Programming
See All in Programming
大LLM時代にこの先生きのこるには-ITエンジニア編
fumiyakume
8
3.3k
プロフェッショナルとしての成長「問題の深掘り」が導く真のスキルアップ / issue-analysis-and-skill-up
minodriven
8
1.9k
ウォンテッドリーの「ココロオドル」モバイル開発 / Wantedly's "kokoro odoru" mobile development
kubode
1
270
flutter_kaigi_mini_4.pdf
nobu74658
0
150
Ruby on Railroad: The Power of Visualizing CFG
ydah
0
300
20250426 GDGoC 合同新歓 - GDGoC のススメ
getty708
0
110
個人開発の学生アプリが企業譲渡されるまで
akidon0000
2
1.2k
エンジニア向けCursor勉強会 @ SmartHR
yukisnow1823
3
12k
Lambda(Python)の リファクタリングが好きなんです
komakichi
4
250
Instrumentsを使用した アプリのパフォーマンス向上方法
hinakko
0
240
파급효과: From AI to Android Development
l2hyunwoo
0
160
The Nature of Complexity in John Ousterhout’s Philosophy of Software Design
philipschwarz
PRO
0
160
Featured
See All Featured
KATA
mclloyd
29
14k
How STYLIGHT went responsive
nonsquared
100
5.5k
Site-Speed That Sticks
csswizardry
6
530
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
129
19k
Raft: Consensus for Rubyists
vanstee
137
6.9k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
45
7.2k
GitHub's CSS Performance
jonrohan
1031
460k
RailsConf 2023
tenderlove
30
1.1k
The Invisible Side of Design
smashingmag
299
50k
Bash Introduction
62gerente
612
210k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
3.8k
Unsuck your backbone
ammeep
671
57k
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_