More Related Content Similar to 以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用 (20) More from Shengyou Fan (18) 以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用21. 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)
}
}
}
22. pt.3
(iOS )
— struct ContentView: View {
@State private var passwordText = "!"
var body: some View {
Text(passwordText)
Button(action: {
passwordText = PasswordGenerator()
.generate(length: 10)
}) {
Text(" ")
}
}
}
24. pt.1
(expect )
—
// shared class
class Detector {
fun detect(): String {
return Platform().platform
}
}
// expect
expect class Platform() {
val platform: String
}
25. 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
}
26. pt.3
(Android )
— class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// ...
val messageTextView: TextView = findViewById(…)
messageTextView.text = Detector().detect()
}
}
27. pt.4
(iOS )
— struct ContentView: View {
@State private var messageText = Detector().detect()
var body: some View {
Text(messageText)
.font(.subheadline)
.foregroundColor(messageTextColor)
}
}
30. 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
31. // 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 )
—
33. 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
( )
—
34. 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 )
—
35. 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 )
—
37. • KMM
- UI - UI
- - expect/actual
-
-
- Multiplatform
- KMM
—
38. • Ktor (HTTP Client)
• kotlinx.serialization
• kotlinx.coroutines
• kotlinx.atomicfu
• SQLDelight
• KaMP Kit
• moko libraries
KMM
—