SlideShare a Scribd company logo
KMM
(Shengyou Fan)
JCConf Taiwan 2021
2021/11/19
Photo by Arnel Hasanovic on Unsplash
—
Mobile https://github.com/shengyou/KmmKungFu
Server https://github.com/shengyou/password-checker
Kotlin
—
• General-purpose
• Static typing
• OOP + FP
• Developed by
JetBrains
• Open Source
(Apache 2.0)
https://kotlinlang.org/
Kotlin
—
Browser
Kotlin/JS
Server
Kotlin/JVM
iOS
Kotlin/Native
Android
Kotlin/JVM
—
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
KMM
—
expect / actual
—
—
KMM opt.1
—
Android
iOS
Android Studio
Xcode
KMM plugin
Simulator
AVD
KMM opt.2
—
Android
iOS
AppCode
KMM plugin

For AppCode
Simulator
AVD
+
KMM Plugin
—
KMM (Step 1)
—
KMM (Step 2)
—
KMM (Step 3)
—
KMM (Step 4)
—
—
• androidApp
• iosApp
• shared
- commonMain
- androidMain
- iosMain
•
-
• API
-
• Multiplatform
- HTTP API
—
—
pt.1
( )
—
class PasswordGenerator {
private val chars = ...
fun generate(length: Int): String {
// ...
}
}
pt.2
(Android )
— class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// ...
val passwordTextView: TextView = findViewById(...)
val generateButton: Button = findViewById(...)
generateButton.setOnClickListener {
passwordTextView.text = PasswordGenerator()
.generate(7)
}
}
}
pt.3
(iOS )
— struct ContentView: View {
@State private var passwordText = "!"
var body: some View {
Text(passwordText)
Button(action: {
passwordText = PasswordGenerator()
.generate(length: 10)
}) {
Text(" ")
}
}
}
—
pt.1
(expect )
—
// shared class
class Detector {
fun detect(): String {
return Platform().platform
}
}
// expect
expect class Platform() {
val platform: String
}
pt.2
(actual )
—
// androidMain
actual class Platform actual constructor() {
actual val platform: String =
"Android version" +
android.os.Build.VERSION.SDK_INT
}
// iosMain
actual class Platform actual constructor() {
actual val platform: String =
UIDevice.currentDevice.systemName() +
" version " +
UIDevice.currentDevice.systemVersion
}
pt.3
(Android )
— class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// ...
val messageTextView: TextView = findViewById(…)
messageTextView.text = Detector().detect()
}
}
pt.4
(iOS )
— struct ContentView: View {
@State private var messageText = Detector().detect()
var body: some View {
Text(messageText)
.font(.subheadline)
.foregroundColor(messageTextColor)
}
}
API
—
—
Mobile API Server
(KMM + Ktor Client) (Ktor Server)
API pt.1
( )
—
kotlin {
// ...
sourceSets {
val commonMain by getting {
dependencies {
// Ktor
implementation("io.ktor:ktor-client-core:$ktorVersion")
implementation("io.ktor:ktor-client-serialization:$ktorVersion")
// Serialization
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$ver")
}
}
val androidMain by getting {
dependencies {
implementation("io.ktor:ktor-client-android:$ktorVersion")
}
}
val iosMain by getting {
dependencies {
implementation("io.ktor:ktor-client-ios:$ktorVersion")
}
}
}
}
1. Ktor Client
2. kotlinx.serialization
// shared
expect fun httpClient(config: HttpClientConfig<*>.() -> Unit): HttpClient
// androidMain
actual fun httpClient(config: HttpClientConfig<*>.() -> Unit) = HttpClient(Android) {
config(this)
engine {
connectTimeout = 100_000
socketTimeout = 100_000
}
}
// iosMain
actual fun httpClient(config: HttpClientConfig<*>.() -> Unit) = HttpClient(Ios) {
config(this)
engine {
configureRequest {
setAllowsCellularAccess(true)
}
}
}
API pt.2
(expect / actual )
—
@Serializable
data class InspectRequest(
val password: String
)
@Serializable
data class InspectResponse(
val result: Boolean,
val message: String
)
API pt.4
(DTO )
—
class Validator {
private val httpClient = httpClient {
install(JsonFeature) {
serializer = KotlinxSerializer()
}
}
suspend fun inspect(password: String): InspectResponse {
return httpClient.post("...") {
accept(ContentType.Application.Json)
contentType(ContentType.Application.Json)
body = InspectRequest(password)
}
}
}
API pt.3
( )
—
class MainActivity : AppCompatActivity() {
private val validator = Validator()
private val mainScope = MainScope()
val inspectButton: Button = findViewById(...)
inspectButton.setOnClickListener {
mainScope.launch {
kotlin.runCatching {
validator.inspect(...)
}.onSuccess {
messageTextView.text = it.message
}
}
}
}
API pt.5
(Android )
—
struct HttpClientView: View {
let validator = Validator()
func validate() {
validator.inspect(password: pw) { response, error in
if let response = response {
self.messageText = response.message
} else if let error = error {
self.messageText = "Error: (error)"
}
}
}
var body: some View {
Button(action: {
validate()
}) {
// ...
}
}
}
API pt.6
(iOS )
—
Browser
Kotlin/JS
Server
Kotlin/JVM
iOS
Kotlin/Native
Android
Kotlin/JVM
- Kotlin
—
• KMM
- UI - UI
- - expect/actual
-
-
- Multiplatform
- KMM
—
• Ktor (HTTP Client)
• kotlinx.serialization
• kotlinx.coroutines
• kotlinx.atomicfu
• SQLDelight
• KaMP Kit
• moko libraries
KMM
—
—
https://kotlinlang.org/docs/mobile/samples.html
KMM
—
https://kotlinlang.org/lp/mobile/case-studies/
Kotlin
—
kotlin.tips
https://tw.kotlin.tips
Tips
—
https://tw.intellij.tips
Kotlin
—
Line Telegram
—
Coding
Kraftsman
(Shengyou Fan)
shengyou.fan@jetbrains.com
Q&A
—
Kotlin Multiplatform Mobile

More Related Content

PDF
[PHP 也有 Day #64] PHP 升級指南
PDF
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
PDF
初探 Kotlin Multiplatform
PDF
날로 먹는 Django admin 활용
PDF
Introduction to kotlin coroutines
PDF
[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇
PDF
老派浪漫:用 Kotlin 寫 Command Line 工具
PPTX
Angular Data Binding
[PHP 也有 Day #64] PHP 升級指南
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
初探 Kotlin Multiplatform
날로 먹는 Django admin 활용
Introduction to kotlin coroutines
[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇
老派浪漫:用 Kotlin 寫 Command Line 工具
Angular Data Binding

What's hot (20)

PDF
introduction to Vue.js 3
PDF
Coroutines for Kotlin Multiplatform in Practise
PDF
Kotlin Coroutines. Flow is coming
PDF
Usb接続するアプリを開発した時に試行錯誤した事
PDF
Connecting Connect with Spring Boot
PDF
[Golang] 以 Mobile App 工程師視角,帶你進入 Golang 的世界 (Introduction of GoLang)
PPTX
Integrating microservices with apache camel on kubernetes
PDF
[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式
PDF
今さらWPF? いいえ、今こそWPF!
PDF
점진적인 레거시 웹 애플리케이션 개선 과정
PDF
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
PDF
[COSCUP 2022] Kotlin Collection 遊樂園
PPTX
Spring Security 5
PDF
Angular Advanced Routing
PDF
Introduction to Coroutines @ KotlinConf 2017
PDF
Why Vue.js?
PDF
Angular Directives
PDF
UniRx - Reactive Extensions for Unity(EN)
PDF
[NDC07] 게임 개발에서의 클라이언트 보안 - 송창규
PDF
NDC2017 언리얼엔진4 디버깅 101 - 게임 기획자, 프로그래머가 버그와 만났을 때 사용할 수 있는 지침들
introduction to Vue.js 3
Coroutines for Kotlin Multiplatform in Practise
Kotlin Coroutines. Flow is coming
Usb接続するアプリを開発した時に試行錯誤した事
Connecting Connect with Spring Boot
[Golang] 以 Mobile App 工程師視角,帶你進入 Golang 的世界 (Introduction of GoLang)
Integrating microservices with apache camel on kubernetes
[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式
今さらWPF? いいえ、今こそWPF!
점진적인 레거시 웹 애플리케이션 개선 과정
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
[COSCUP 2022] Kotlin Collection 遊樂園
Spring Security 5
Angular Advanced Routing
Introduction to Coroutines @ KotlinConf 2017
Why Vue.js?
Angular Directives
UniRx - Reactive Extensions for Unity(EN)
[NDC07] 게임 개발에서의 클라이언트 보안 - 송창규
NDC2017 언리얼엔진4 디버깅 101 - 게임 기획자, 프로그래머가 버그와 만났을 때 사용할 수 있는 지침들
Ad

More from Shengyou Fan (20)

PDF
[JCConf 2024] Kotlin/Wasm:為 Kotlin 多平台帶來更多可能性
PDF
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
PDF
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
PDF
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
PDF
How I make a podcast website using serverless technology in 2023
PDF
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
PDF
Using the Exposed SQL Framework to Manage Your Database
PDF
[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具
PDF
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
PDF
Composer 經典食譜
PDF
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
PDF
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
PDF
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
PDF
[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置
PDF
用 Kotlin 打造讀書會小幫手
PDF
Kotlin 讀書會第三梯次第一章
PDF
用 OPENRNDR 將 Chatbot 訊息視覺化
PDF
[PHP 也有 Day] 垃圾留言守城記 - 用 Laravel 阻擋 SPAM 留言的奮鬥史
PDF
Ktor 部署攻略 - 老派 Fat Jar 大法
PDF
以 Kotlin 快速打造 Mobile Backend
[JCConf 2024] Kotlin/Wasm:為 Kotlin 多平台帶來更多可能性
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
How I make a podcast website using serverless technology in 2023
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
Using the Exposed SQL Framework to Manage Your Database
[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
Composer 經典食譜
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置
用 Kotlin 打造讀書會小幫手
Kotlin 讀書會第三梯次第一章
用 OPENRNDR 將 Chatbot 訊息視覺化
[PHP 也有 Day] 垃圾留言守城記 - 用 Laravel 阻擋 SPAM 留言的奮鬥史
Ktor 部署攻略 - 老派 Fat Jar 大法
以 Kotlin 快速打造 Mobile Backend
Ad

以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用