Skill 详情
kotlin-multiplatform
Relevant when Android is part of a KMP product, but cross-platform by design.
使用前先检查
自动化审核只检查相关性,不代表安全审查或推荐。使用前请阅读来源中的说明。
SKILL.md
这段内容是审核时保存的快照。外部来源才是完整且最新的版本。
---
name: kotlin-multiplatform
description: >-
KMP/CMP shared business logic, Compose Multiplatform, expect/actual, Ktor, SQLDelight, and platform-specific implementations. Use when building cross-platform Kotlin applications for Android, iOS, desktop, or web.
---
# Kotlin Multiplatform Skill
Shared business logic and optional shared UI across Android, iOS, desktop, and web.
---
## Project Structure
```
project/
├── composeApp/ # Shared Compose UI (if using CMP)
│ └── src/
│ ├── commonMain/ # Shared UI code
│ ├── androidMain/ # Android-specific UI
│ ├── iosMain/ # iOS-specific UI
│ └── desktopMain/ # Desktop-specific UI
├── shared/ # Shared business logic (KMP)
│ └── src/
│ ├── commonMain/ # Shared code
│ │ └── kotlin/
│ │ ├── data/ # Repositories, data sources
│ │ ├── domain/ # Use cases, models
│ │ └── platform/ # expect declarations
│ ├── androidMain/ # actual implementations
│ ├── iosMain/ # actual implementations
│ └── commonTest/ # Shared tests
├── androidApp/ # Android entry point
├── iosApp/ # iOS entry point (Xcode project)
├── build.gradle.kts
└── settings.gradle.kts
```
---
## expect/actual Pattern
```kotlin
// commonMain - expect declaration
expect class PlatformContext
expect fun getPlatformName(): String
expect fun createHttpClient(): HttpClient
// androidMain - actual implementation
actual class PlatformContext(val context: android.content.Context)
actual fun getPlatformName(): String = "Android ${Build.VERSION.SDK_INT}"
actual fun createHttpClient(): HttpClient = HttpClient(OkHttp) {
install(ContentNegotiation) { json() }
}
// iosMain - actual implementation
actual class PlatformContext
actual fun getPlatformName(): String = UIDevice.currentDevice.systemName()
actual fun createHttpClient(): HttpClient = HttpClient(Darwin) {
install(ContentNegotiation) { json() }
}
```
---
## Key Libraries
| Library | Purpose | Multiplatform? |
|---------|---------|----------------|
| Ktor | HTTP client | Yes |
| kotlinx.serialization | JSON parsing | Yes |
| kotlinx.coroutines | Async/concurrency | Yes |
| SQLDelight | Local database | Yes |
| Koin | Dependency injection | Yes |
| Compose Multiplatform | Shared UI | Yes |
| kotlinx.datetime | Date/time | Yes |
| Napier | Logging | Yes |
---
## Networking with Ktor
```kotlin
// commonMain
class ApiClient(private val httpClient: HttpClient) {
suspend fun getUsers(): List<User> {
return httpClient.get("https://api.example.com/users").body()
}
suspend fun createUser(input: CreateUserInput): User {
return httpClient.post("https://api.example.com/users") {
contentType(ContentType.Application.Json)
setBody(input)
}.body()
}
}
@Serializable
data class User(
val id: String,
val name: String,
val email: String,
)
```
---
## Local Storage with SQLDelight
```sql
-- src/commonMain/sqldelight/com/example/UserQueries.sq
CREATE TABLE user (
id TEXT NOT NULL PRIMARY KEY,
name TEXT NOT NULL,
email TEXT NOT NULL,
cached_at INTEGER NOT NULL
);
selectAll:
SELECT * FROM user ORDER BY name;
insertOrReplace:
INSERT OR REPLACE INTO user (id, name, email, cached_at)
VALUES (?, ?, ?, ?);
deleteById:
DELETE FROM user WHERE id = ?;
```
---
## Compose Multiplatform UI
```kotlin
// commonMain - Shared composable
@Composable
fun UserListScreen(viewModel: UserListViewModel) {
val users by viewModel.users.collectAsState()
val isLoading by viewModel.isLoading.collectAsState()
Scaffold(
topBar = { TopAppBar(title = { Text("Users") }) }
) { padding ->
if (isLoading) {
CircularProgressIndicator(modifier = Modifier.padding(padding))
} else {
在 GitHub 阅读完整来源 (打开外部页面)