SlideShare a Scribd company logo
1 of 45
Download to read offline
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
—
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

What's hot

[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...Shengyou Fan
 
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀Shengyou Fan
 
How I make a podcast website using serverless technology in 2023
How I make a podcast website using serverless technology in 2023How I make a podcast website using serverless technology in 2023
How I make a podcast website using serverless technology in 2023Shengyou Fan
 
AstriCon 2017 - Docker Swarm & Asterisk
AstriCon 2017  - Docker Swarm & AsteriskAstriCon 2017  - Docker Swarm & Asterisk
AstriCon 2017 - Docker Swarm & AsteriskEvan McGee
 
Build your own embedded linux distributions by yocto project
Build your own embedded linux distributions by yocto projectBuild your own embedded linux distributions by yocto project
Build your own embedded linux distributions by yocto projectYen-Chin Lee
 
How shit works: the CPU
How shit works: the CPUHow shit works: the CPU
How shit works: the CPUTomer Gabel
 
Coroutines for Kotlin Multiplatform in Practise
Coroutines for Kotlin Multiplatform in PractiseCoroutines for Kotlin Multiplatform in Practise
Coroutines for Kotlin Multiplatform in PractiseChristian Melchior
 
KMM survival guide: how to tackle struggles between Kotlin and Swift
KMM survival guide: how to tackle struggles between Kotlin and SwiftKMM survival guide: how to tackle struggles between Kotlin and Swift
KMM survival guide: how to tackle struggles between Kotlin and SwiftCommit University
 
Deep dive into Vue.js
Deep dive into Vue.jsDeep dive into Vue.js
Deep dive into Vue.js선협 이
 
PHPCon China 2016 - 從學徒變大師:談 Laravel 框架擴充與套件開發
PHPCon China 2016 - 從學徒變大師:談 Laravel 框架擴充與套件開發PHPCon China 2016 - 從學徒變大師:談 Laravel 框架擴充與套件開發
PHPCon China 2016 - 從學徒變大師:談 Laravel 框架擴充與套件開發Shengyou Fan
 
JJUG CCC 2017 Fall オレオレJVM言語を作ってみる
JJUG CCC 2017 Fall オレオレJVM言語を作ってみるJJUG CCC 2017 Fall オレオレJVM言語を作ってみる
JJUG CCC 2017 Fall オレオレJVM言語を作ってみるKoichi Sakata
 
Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017Roman Elizarov
 
The Microkernel Mach Under NeXTSTEP
The Microkernel Mach Under NeXTSTEPThe Microkernel Mach Under NeXTSTEP
The Microkernel Mach Under NeXTSTEPGregor Schmidt
 
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀Shengyou Fan
 
Project ACRN hypervisor introduction
Project ACRN hypervisor introduction Project ACRN hypervisor introduction
Project ACRN hypervisor introduction Project ACRN
 
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率Shengyou Fan
 
Why I ❤️ Kotlin Multiplatform (and want YOU to also ❤️ Kotlin Multiplatform)
Why I ❤️ Kotlin Multiplatform (and want YOU to also ❤️ Kotlin Multiplatform)Why I ❤️ Kotlin Multiplatform (and want YOU to also ❤️ Kotlin Multiplatform)
Why I ❤️ Kotlin Multiplatform (and want YOU to also ❤️ Kotlin Multiplatform)Derek Lee Boire
 
Google play加入測試人員步驟
Google play加入測試人員步驟Google play加入測試人員步驟
Google play加入測試人員步驟newegg
 
Kotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is comingKotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is comingKirill Rozov
 

What's hot (20)

[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
 
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
 
How I make a podcast website using serverless technology in 2023
How I make a podcast website using serverless technology in 2023How I make a podcast website using serverless technology in 2023
How I make a podcast website using serverless technology in 2023
 
AstriCon 2017 - Docker Swarm & Asterisk
AstriCon 2017  - Docker Swarm & AsteriskAstriCon 2017  - Docker Swarm & Asterisk
AstriCon 2017 - Docker Swarm & Asterisk
 
Build your own embedded linux distributions by yocto project
Build your own embedded linux distributions by yocto projectBuild your own embedded linux distributions by yocto project
Build your own embedded linux distributions by yocto project
 
How shit works: the CPU
How shit works: the CPUHow shit works: the CPU
How shit works: the CPU
 
Coroutines for Kotlin Multiplatform in Practise
Coroutines for Kotlin Multiplatform in PractiseCoroutines for Kotlin Multiplatform in Practise
Coroutines for Kotlin Multiplatform in Practise
 
KMM survival guide: how to tackle struggles between Kotlin and Swift
KMM survival guide: how to tackle struggles between Kotlin and SwiftKMM survival guide: how to tackle struggles between Kotlin and Swift
KMM survival guide: how to tackle struggles between Kotlin and Swift
 
Deep dive into Vue.js
Deep dive into Vue.jsDeep dive into Vue.js
Deep dive into Vue.js
 
LLVM introduction
LLVM introductionLLVM introduction
LLVM introduction
 
PHPCon China 2016 - 從學徒變大師:談 Laravel 框架擴充與套件開發
PHPCon China 2016 - 從學徒變大師:談 Laravel 框架擴充與套件開發PHPCon China 2016 - 從學徒變大師:談 Laravel 框架擴充與套件開發
PHPCon China 2016 - 從學徒變大師:談 Laravel 框架擴充與套件開發
 
JJUG CCC 2017 Fall オレオレJVM言語を作ってみる
JJUG CCC 2017 Fall オレオレJVM言語を作ってみるJJUG CCC 2017 Fall オレオレJVM言語を作ってみる
JJUG CCC 2017 Fall オレオレJVM言語を作ってみる
 
Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017
 
The Microkernel Mach Under NeXTSTEP
The Microkernel Mach Under NeXTSTEPThe Microkernel Mach Under NeXTSTEP
The Microkernel Mach Under NeXTSTEP
 
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
 
Project ACRN hypervisor introduction
Project ACRN hypervisor introduction Project ACRN hypervisor introduction
Project ACRN hypervisor introduction
 
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
 
Why I ❤️ Kotlin Multiplatform (and want YOU to also ❤️ Kotlin Multiplatform)
Why I ❤️ Kotlin Multiplatform (and want YOU to also ❤️ Kotlin Multiplatform)Why I ❤️ Kotlin Multiplatform (and want YOU to also ❤️ Kotlin Multiplatform)
Why I ❤️ Kotlin Multiplatform (and want YOU to also ❤️ Kotlin Multiplatform)
 
Google play加入測試人員步驟
Google play加入測試人員步驟Google play加入測試人員步驟
Google play加入測試人員步驟
 
Kotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is comingKotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is coming
 

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

Erlang Practice
Erlang PracticeErlang Practice
Erlang Practicelitaocheng
 
Android系统移植技术详解
Android系统移植技术详解Android系统移植技术详解
Android系统移植技术详解zzc89522
 
Koa 正在等一個人
Koa 正在等一個人Koa 正在等一個人
Koa 正在等一個人Fred Chien
 
利用Signalr打造即時通訊@Tech day geek
利用Signalr打造即時通訊@Tech day geek利用Signalr打造即時通訊@Tech day geek
利用Signalr打造即時通訊@Tech day geekJohnson Gau
 
基于Eclipse和hadoop平台应用开发入门手册
基于Eclipse和hadoop平台应用开发入门手册基于Eclipse和hadoop平台应用开发入门手册
基于Eclipse和hadoop平台应用开发入门手册Zhen Li
 
构建ActionScript游戏服务器,支持超过15000并发连接
构建ActionScript游戏服务器,支持超过15000并发连接 构建ActionScript游戏服务器,支持超过15000并发连接
构建ActionScript游戏服务器,支持超过15000并发连接 Renaun Erickson
 
使用 Java 上的 future/promise API
使用 Java 上的 future/promise  API使用 Java 上的 future/promise  API
使用 Java 上的 future/promise APIkoji lin
 
以HTML5和COIMOTION打造跨平台App
以HTML5和COIMOTION打造跨平台App以HTML5和COIMOTION打造跨平台App
以HTML5和COIMOTION打造跨平台AppBen Lue
 
廖雪峰 Saa s ovp
廖雪峰 Saa s ovp廖雪峰 Saa s ovp
廖雪峰 Saa s ovpdrewz lin
 
CYBERSEC 2020 臺灣資安大會 - 第一次使用 k8s 就不埋漏洞
CYBERSEC 2020 臺灣資安大會 - 第一次使用 k8s 就不埋漏洞CYBERSEC 2020 臺灣資安大會 - 第一次使用 k8s 就不埋漏洞
CYBERSEC 2020 臺灣資安大會 - 第一次使用 k8s 就不埋漏洞Secview
 
Node js实践
Node js实践Node js实践
Node js实践myzykj
 
Android应用开发 - 沈大海
Android应用开发 - 沈大海Android应用开发 - 沈大海
Android应用开发 - 沈大海Shaoning Pan
 
Graphic programming in js
Graphic programming in jsGraphic programming in js
Graphic programming in jsjay li
 
HTML+COIMOTION 開發跨平台 app
HTML+COIMOTION 開發跨平台 appHTML+COIMOTION 開發跨平台 app
HTML+COIMOTION 開發跨平台 appBen Lue
 
Tec android-01
Tec android-01Tec android-01
Tec android-01jinkaichen
 
COSCUP 2016 Workshop: 用 Docker 架設班級 git-it 練習環境
COSCUP 2016 Workshop: 用 Docker 架設班級 git-it 練習環境COSCUP 2016 Workshop: 用 Docker 架設班級 git-it 練習環境
COSCUP 2016 Workshop: 用 Docker 架設班級 git-it 練習環境均民 戴
 
容器與 Gitlab CI 應用
容器與 Gitlab CI 應用容器與 Gitlab CI 應用
容器與 Gitlab CI 應用Philip Zheng
 
容器驅動開發 - .NET Conf 2017 @ 台中
容器驅動開發 - .NET Conf 2017 @ 台中容器驅動開發 - .NET Conf 2017 @ 台中
容器驅動開發 - .NET Conf 2017 @ 台中Andrew Wu
 
张所勇:前端开发工具推荐
张所勇:前端开发工具推荐张所勇:前端开发工具推荐
张所勇:前端开发工具推荐zhangsuoyong
 

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

Erlang Practice
Erlang PracticeErlang Practice
Erlang Practice
 
Android系统移植技术详解
Android系统移植技术详解Android系统移植技术详解
Android系统移植技术详解
 
Koa 正在等一個人
Koa 正在等一個人Koa 正在等一個人
Koa 正在等一個人
 
利用Signalr打造即時通訊@Tech day geek
利用Signalr打造即時通訊@Tech day geek利用Signalr打造即時通訊@Tech day geek
利用Signalr打造即時通訊@Tech day geek
 
基于Eclipse和hadoop平台应用开发入门手册
基于Eclipse和hadoop平台应用开发入门手册基于Eclipse和hadoop平台应用开发入门手册
基于Eclipse和hadoop平台应用开发入门手册
 
构建ActionScript游戏服务器,支持超过15000并发连接
构建ActionScript游戏服务器,支持超过15000并发连接 构建ActionScript游戏服务器,支持超过15000并发连接
构建ActionScript游戏服务器,支持超过15000并发连接
 
使用 Java 上的 future/promise API
使用 Java 上的 future/promise  API使用 Java 上的 future/promise  API
使用 Java 上的 future/promise API
 
以HTML5和COIMOTION打造跨平台App
以HTML5和COIMOTION打造跨平台App以HTML5和COIMOTION打造跨平台App
以HTML5和COIMOTION打造跨平台App
 
廖雪峰 Saa s ovp
廖雪峰 Saa s ovp廖雪峰 Saa s ovp
廖雪峰 Saa s ovp
 
CYBERSEC 2020 臺灣資安大會 - 第一次使用 k8s 就不埋漏洞
CYBERSEC 2020 臺灣資安大會 - 第一次使用 k8s 就不埋漏洞CYBERSEC 2020 臺灣資安大會 - 第一次使用 k8s 就不埋漏洞
CYBERSEC 2020 臺灣資安大會 - 第一次使用 k8s 就不埋漏洞
 
Berserk js
Berserk jsBerserk js
Berserk js
 
Node js实践
Node js实践Node js实践
Node js实践
 
Android应用开发 - 沈大海
Android应用开发 - 沈大海Android应用开发 - 沈大海
Android应用开发 - 沈大海
 
Graphic programming in js
Graphic programming in jsGraphic programming in js
Graphic programming in js
 
HTML+COIMOTION 開發跨平台 app
HTML+COIMOTION 開發跨平台 appHTML+COIMOTION 開發跨平台 app
HTML+COIMOTION 開發跨平台 app
 
Tec android-01
Tec android-01Tec android-01
Tec android-01
 
COSCUP 2016 Workshop: 用 Docker 架設班級 git-it 練習環境
COSCUP 2016 Workshop: 用 Docker 架設班級 git-it 練習環境COSCUP 2016 Workshop: 用 Docker 架設班級 git-it 練習環境
COSCUP 2016 Workshop: 用 Docker 架設班級 git-it 練習環境
 
容器與 Gitlab CI 應用
容器與 Gitlab CI 應用容器與 Gitlab CI 應用
容器與 Gitlab CI 應用
 
容器驅動開發 - .NET Conf 2017 @ 台中
容器驅動開發 - .NET Conf 2017 @ 台中容器驅動開發 - .NET Conf 2017 @ 台中
容器驅動開發 - .NET Conf 2017 @ 台中
 
张所勇:前端开发工具推荐
张所勇:前端开发工具推荐张所勇:前端开发工具推荐
张所勇:前端开发工具推荐
 

More from Shengyou Fan

[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能Shengyou Fan
 
Using the Exposed SQL Framework to Manage Your Database
Using the Exposed SQL Framework to Manage Your DatabaseUsing the Exposed SQL Framework to Manage Your Database
Using the Exposed SQL Framework to Manage Your DatabaseShengyou Fan
 
[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具
[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具
[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具Shengyou Fan
 
Composer 經典食譜
Composer 經典食譜Composer 經典食譜
Composer 經典食譜Shengyou Fan
 
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS AggregatorShengyou Fan
 
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON APIShengyou Fan
 
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin ServerlessShengyou Fan
 
[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置
[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置
[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置Shengyou Fan
 
用 Kotlin 打造讀書會小幫手
用 Kotlin 打造讀書會小幫手用 Kotlin 打造讀書會小幫手
用 Kotlin 打造讀書會小幫手Shengyou Fan
 
Kotlin 讀書會第三梯次第一章
Kotlin 讀書會第三梯次第一章Kotlin 讀書會第三梯次第一章
Kotlin 讀書會第三梯次第一章Shengyou Fan
 
用 OPENRNDR 將 Chatbot 訊息視覺化
用 OPENRNDR 將 Chatbot 訊息視覺化用 OPENRNDR 將 Chatbot 訊息視覺化
用 OPENRNDR 將 Chatbot 訊息視覺化Shengyou Fan
 
[PHP 也有 Day] 垃圾留言守城記 - 用 Laravel 阻擋 SPAM 留言的奮鬥史
[PHP 也有 Day] 垃圾留言守城記 - 用 Laravel 阻擋 SPAM 留言的奮鬥史[PHP 也有 Day] 垃圾留言守城記 - 用 Laravel 阻擋 SPAM 留言的奮鬥史
[PHP 也有 Day] 垃圾留言守城記 - 用 Laravel 阻擋 SPAM 留言的奮鬥史Shengyou Fan
 
Ktor 部署攻略 - 老派 Fat Jar 大法
Ktor 部署攻略 - 老派 Fat Jar 大法Ktor 部署攻略 - 老派 Fat Jar 大法
Ktor 部署攻略 - 老派 Fat Jar 大法Shengyou Fan
 
以 Kotlin 快速打造 Mobile Backend
以 Kotlin 快速打造 Mobile Backend以 Kotlin 快速打造 Mobile Backend
以 Kotlin 快速打造 Mobile BackendShengyou Fan
 
Kotlin 一條龍 - 打造全平台應用
Kotlin 一條龍 - 打造全平台應用Kotlin 一條龍 - 打造全平台應用
Kotlin 一條龍 - 打造全平台應用Shengyou Fan
 
[HKOSCon 2020] Build an api service using ktor rapidly
[HKOSCon 2020] Build an api service using ktor rapidly[HKOSCon 2020] Build an api service using ktor rapidly
[HKOSCon 2020] Build an api service using ktor rapidlyShengyou Fan
 
用 Kotlin 做自動化工具
用 Kotlin 做自動化工具用 Kotlin 做自動化工具
用 Kotlin 做自動化工具Shengyou Fan
 

More from Shengyou Fan (17)

[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
 
Using the Exposed SQL Framework to Manage Your Database
Using the Exposed SQL Framework to Manage Your DatabaseUsing the Exposed SQL Framework to Manage Your Database
Using the Exposed SQL Framework to Manage Your Database
 
[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具
[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具
[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具
 
Composer 經典食譜
Composer 經典食譜Composer 經典食譜
Composer 經典食譜
 
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
 
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
 
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
 
[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置
[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置
[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置
 
用 Kotlin 打造讀書會小幫手
用 Kotlin 打造讀書會小幫手用 Kotlin 打造讀書會小幫手
用 Kotlin 打造讀書會小幫手
 
Kotlin 讀書會第三梯次第一章
Kotlin 讀書會第三梯次第一章Kotlin 讀書會第三梯次第一章
Kotlin 讀書會第三梯次第一章
 
用 OPENRNDR 將 Chatbot 訊息視覺化
用 OPENRNDR 將 Chatbot 訊息視覺化用 OPENRNDR 將 Chatbot 訊息視覺化
用 OPENRNDR 將 Chatbot 訊息視覺化
 
[PHP 也有 Day] 垃圾留言守城記 - 用 Laravel 阻擋 SPAM 留言的奮鬥史
[PHP 也有 Day] 垃圾留言守城記 - 用 Laravel 阻擋 SPAM 留言的奮鬥史[PHP 也有 Day] 垃圾留言守城記 - 用 Laravel 阻擋 SPAM 留言的奮鬥史
[PHP 也有 Day] 垃圾留言守城記 - 用 Laravel 阻擋 SPAM 留言的奮鬥史
 
Ktor 部署攻略 - 老派 Fat Jar 大法
Ktor 部署攻略 - 老派 Fat Jar 大法Ktor 部署攻略 - 老派 Fat Jar 大法
Ktor 部署攻略 - 老派 Fat Jar 大法
 
以 Kotlin 快速打造 Mobile Backend
以 Kotlin 快速打造 Mobile Backend以 Kotlin 快速打造 Mobile Backend
以 Kotlin 快速打造 Mobile Backend
 
Kotlin 一條龍 - 打造全平台應用
Kotlin 一條龍 - 打造全平台應用Kotlin 一條龍 - 打造全平台應用
Kotlin 一條龍 - 打造全平台應用
 
[HKOSCon 2020] Build an api service using ktor rapidly
[HKOSCon 2020] Build an api service using ktor rapidly[HKOSCon 2020] Build an api service using ktor rapidly
[HKOSCon 2020] Build an api service using ktor rapidly
 
用 Kotlin 做自動化工具
用 Kotlin 做自動化工具用 Kotlin 做自動化工具
用 Kotlin 做自動化工具
 

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