Kotlin/Native
「使ってみた」の一歩先へ
M3 Inc. Takaki Hoshikawa
Profile
- 星川 貴樹
○ @oboenikui
- FY17新卒入社 (2年目)
- Androidエンジニア, セキュリティエンジニア?
- Kotlin/Native歴 1年2ヶ月
- 業務ではまだ使ってません……
今日話すこと
- Kotlin/Nativeの誕生〜現在
- Multiplatform project (MPP) について
- 「Kotlin/Nativeはキワモノ」という認識を改める
- 「Kotlin/Nativeとりあえず使ってみました」
というフェーズから一歩進む
Kotlin/Nativeを知る
Kotlin/Nativeとは
Kotlin→LLVM IRコンパイラを含むツール
LLVM IR
…
…
Kotlin/Nativeとは
Kotlin→LLVM IRコンパイラを含むツール
…
…
コンパイル前の言語は理論上
は混在していても大丈夫
LLVM IR
Kotlin/Nativeとは
Kotlin→LLVM IRコンパイラを含むツール
…
…
豊富なアーキテクチャ
をサポート
LLVM IR
Kotlin/Nativeの歩み
登場 現在
2017
04
2018
11
Kotlin/Nativeの歩み
v0.1〜0.2 基本的な機能
- Linuxなどで動作
- Cのヘッダーファイルを解釈することができた
ので、Cで書けるものは実装可能だった
- OpenGLをはじめとしたLinuxのライブラ
リなど
2017
04
2018
11
Kotlin/Nativeの歩み
2017
04
v0.3
- Windows, Android NDK対応
- ワーカー対応 など
06
2018
11
Kotlin/Nativeの歩み
v0.4〜0.5 基本的なサポートが出揃う
- iOS (arm64), macOS, WebAssemblyなど対応
- kotlin.mathパッケージが実装された
- 初のIDEサポート (CLion)
- Kotlin 1.2対応
06 11~12
2017
04
2018
11
Kotlin/Nativeの歩み
v0.6 実用面の強化
- MPP対応
- ObjCやCの相互運用が可能に
- その他ターゲットの追加など
06 11~12
2017
04
2018
02~03 11
Kotlin/Nativeの歩み
v0.7 実用面の強化
- ObjC, Swfitの相互運用改善
- Maven artifacts対応
- AppCode, iOSシミュレータ対応
06 11~12 04~05
2017
04
2018
02~03 11
Kotlin/Nativeの歩み
v0.8
- JVM, JSと共通の
stdlibに
- kotlin.random.*な
どの実装
06 11~12 04~05 06~08
2017
04
2018
02~03 11
Kotlin/Nativeの歩み
11
v0.9~Beta (現在)
- 安定版コルーチンサポート
- Kotlin 1.3対応など
06 11~12 04~05 06~08
2017
04
2018
02~03
Kotlin/Nativeの使い道
Kotlin/Nativeに対する疑問・不安
- Java資産の使えないKotlinに価値ある?
- Kotlin stdlibにない機能はどうするの?
- メモリ管理は大丈夫なの?
-
-
-
Java資産が使えない?
- Java資産をKotlin/Nativeで使うことは当然困難だ
が、ネイティブのライブラリが利用可能
- iOSであればSwift, Objective-Cのライブラリが利用
可能
- MPPなラッパーで対応可能
- でも個人で全て対応しめんてしていくのは大抵面倒なので、OSS
で公開されたものを使うなどが必要
Kotlin stdlib外のライブラリ(公式)
- Coroutines, Serialization
- 既にNative対応済み
- Network I/O
- Ktor ClientがMPPとしてJVM, JS, iOSに対応
↪ JVMはOkHttpをラップしたものを用いる
https://github.com/ktorio/ktor
- File I/O
- kotlinx-ioが進行中
https://github.com/Kotlin/kotlinx-io
Kotlin stdlib外のライブラリ(非公式)
- DI
- Kodeinが対応済み
https://github.com/Kodein-Framework/Kodein-DI/
- Date, Loggerなど
- Korlibsというプロジェクトで提供中
https://korlibs.soywiz.com/
基本的なものは出揃ってきた?
参考になる実装
- kotlinconf-app
https://github.com/jetbrains/kotlinconf-app
- kotlinconf-spinner (AndroidもNDKを使ってる)
https://github.com/jetbrains/kotlinconf-spinner
- KotAcademyPortal (ちょっと古い)
https://github.com/MarcinMoskala/KotAcademyPortal
メモリ管理
- GCを独自実装している
- iOSであればARCが使える
- Cのライブラリを使う場合、メモリ管理されたスコープ内
でallocなどのメモリリークしやすい操作を行う
想定される使い道
- Android, iOS(, Web) の共通モジュール
- サーバーとクライアントのモデルクラス共通化
- Linuxネイティブライブラリ、ソフトウェアの開発
- WebAssembly
[Pickup]
Android, iOSのコードシェア
kotlinconf-app (iOS) の変化
2017/04 2018/1106 11~12 02~03 04~05 06~08
iOSアプリをKotlinで書けるように
なった!
- Kotlinの文法で書けない部分の
みObjC
- 他はフルKotlinでゴリゴリ実装
- MPPは当時JVM, JSのみの対応
kotlinconf-app (iOS) の変化
2017/04 2018/1106 11~12 02~03 04~05 06~08
MVPで実装し全てをKotlinでは書か
ない
- AndroidとModel, Presenter
を共通化、
ViewはSwift
- iOS固有のKotlinコードは
MVPアーキテクチャ
Presenter
ViewModel
MVPアーキテクチャ
Presenter
ViewModel
Common Module
で実装
MVPアーキテクチャ
Presenter
ViewModel
Android
↪Kotlin
iOS
↪Swift
MVPアーキテクチャ
Presenter
ViewModel
クロスプラットフォームでありがちな
iOSデザインにAndroidが引っ張られる
(もしくはその逆)という問題を解決 Android
↪Kotlin
iOS
↪Swift
Kotlin/Nativeを使う
Gradleの設定
plugins {
id 'org.jetbrains.kotlin.multiplatform' version '1.3.0'
}
repositories {
mavenCentral()
}
kotlin {
/* ... */
}
http://kotl.in/multiplatform
Gradleの設定 (kotlinブロック)
kotlin {
targets {
fromPreset(presets.jvm, 'android')
fromPreset(presets.iosArm64, 'ios')
}
sourceSets {
commonMain { /* ... */ }
commonTest { /* ... */ }
androidMain { /* ... */ }
androidTest { /* ... */ }
iosMain { /* ... */ }
iosTest { /* ... */ }
}
} http://kotl.in/multiplatform
Gradleの設定 (kotlinブロック)
kotlin {
targets {
fromPreset(presets.jvm, 'android')
fromPreset(presets.iosArm64, 'ios')
}
sourceSets {
commonMain { /* ... */ }
commonTest { /* ... */ }
androidMain { /* ... */ }
androidTest { /* ... */ }
iosMain { /* ... */ }
iosTest { /* ... */ }
}
}
他に
android js macosX64
mingwX64 linuxX64 wasm32
など
http://kotl.in/multiplatform
Gradleの設定 (kotlinブロック)
kotlin {
targets {
fromPreset(presets.jvm, 'android')
fromPreset(presets.iosArm64, 'ios')
}
sourceSets {
commonMain { /* ... */ }
commonTest { /* ... */ }
androidMain { /* ... */ }
androidTest { /* ... */ }
iosMain { /* ... */ }
iosTest { /* ... */ }
}
}
名前が対応
http://kotl.in/multiplatform
Gradleの設定 (sourceSetsブロック)
commonMain {
implementation 'org.jetbrains.kotlin:kotlin-stdlib'
implementation "io.ktor:ktor-client-core:$ktor_version"
}
androidMain {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kt_version"
implementation "io.ktor:ktor-client-core-jvm:$ktor_version"
}
iosMain {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kt_version"
implementation "io.ktor:ktor-client-ios:$ktor_version"
implementation "io.ktor:ktor-client-core-ios:$ktor_version"
}
ディレクトリ構造
└─ src/
├─ commonMain/
│ └─ kotlin/
├─ commonTest/
│ └─ kotlin/
├─ androidMain/ (Optional)
│ └─ kotlin/
└─ iosMain/ (Optional)
└─ kotlin/
OSごとに別の実装をする場合
// commonMain/kotlin/Time.kt
fun currentTimeSeconds() = currentTimeMillis() / 1000
expect fun currentTimeMillis(): Long
// androidMain/koltin/Time.kt
actual fun currentTimeMillis() = System.currentTimeMillis()
// iosMain/koltin/Time.kt
actual fun currentTimeMillis() {
return (NSDate().timeIntervalSince1970 * 1000).toLong()
}
OSごとに別の実装をする場合
expect class LocalDateTime {
/* ... */
}
// JVM
actual typealias LocalDateTime = java.time.LocalDateTime
Kotlin/Nativeの速度
速いの?
速いの?
- まだJVMより多分遅い
- 最適化作業はまだこれからではないかと思う
Kotlin/JVM Kotlin/Native
821ms 1961ms
参考:アッカーマン関数 Ask(3, 11) の10回平均時間
(2GHz Core i5 / macOS 10.13.6 / kotlin-native 0.9.3)
※ VMのロード時間など考慮できていないので参考程度と捉えてください
Kotlin/Nativeのこれから
今できること
将来的にMPPになる想定のプロジェクトについては
- 分離できる部分のexpect/actual化
- JVM実装だけでもactualで実装する
- 構造が変わるだけで基本的には実装可能
- MPPが提供された(されそうな)ライブラリへの移行
- OkHttp → Ktor client
- Dagger → Kodein
- JSONパーサ → kotlinx-serialization
Kotlin/Nativeが今後使われるには
- KotlinライブラリのMPP対応
- 今ある基本的なライブラリをベースにして、GraphQLクライアントなど、
より発展的なライブラリが出現する必要性
- iOSエンジニアの理解
- iOSエンジニアに便利だと知ってもらう必要
- 更なるIDE対応の強化
- 今はまだバグが結構多い
Have a nice Kotlin!!

Kotlin/Native 「使ってみた」の一歩先へ