Compose
Screen.Recording.2023-05-07.at.9.51.32.PM.mov
Multiplatform simplifies and accelerates UI and share it between Android, IOS, Desktop and Web.
This repository will contain instructions to start your first Compose Multiplatform Project.
Install KMM plugin in Android Studio
- Create a new KMM project using the plugin above
in your settings.gradle
file add the following dependency
pluginManagement {
repositories {
google()
gradlePluginPortal()
mavenCentral()
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") // this one
}
plugins {
kotlin("jvm").version("1.8.21")
kotlin("multiplatform").version("1.8.21")
kotlin("android").version("1.8.21")
id("com.android.application").version("7.4.2")
id("com.android.library").version("7.4.2")
id("org.jetbrains.compose").version("1.4.3")
}
}
in your build.gradle.kts
add compose plugin
plugins {
//trick: for the same plugin versions in all sub-modules
id("com.android.application").version("8.2.0-alpha06").apply(false)
id("com.android.library").version("8.2.0-alpha06").apply(false)
kotlin("android").version("1.8.21").apply(false)
kotlin("multiplatform").version("1.8.21").apply(false)
}
now inside shared module
build.gradle.kts
add these two plugins
plugins {
kotlin("multiplatform")
id("com.android.library")
kotlin("native.cocoapods") // this
id("org.jetbrains.compose") // and this
}
in your kotlin
block add the following lines
iosX64()
iosArm64()
iosSimulatorArm64()
cocoapods {
version = "1.0.0"
summary = "Some description for the Shared Module"
homepage = "Link to the Shared Module homepage"
ios.deploymentTarget = "14.1"
podfile = project.file("../iosApp/Podfile")
framework {
baseName = "shared"
isStatic = true
}
extraSpecAttributes["resources"] = "['src/commonMain/resources/**', 'src/iosMain/resources/**']" // this is for images
}
// in android block add these lines to support common resources
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
sourceSets["main"].res.srcDirs("src/androidMain/res")
sourceSets["main"].resources.srcDirs("src/commonMain/resources")
now BEFORE you sync you need to make sure about the following:
- Install cocoapods
brew install cocoapods
- cd to iosApp and init pod
pod init
- install your pods
pod install
In sourceSets
sourceSets {
val commonMain by getting {
dependencies {
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material)
@OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class)
implementation(compose.components.resources)
}
}
val androidMain by getting {
dependencies {
api("androidx.activity:activity-compose:1.6.1")
api("androidx.appcompat:appcompat:1.6.1")
api("androidx.core:core-ktx:1.9.0")
}
}
val iosX64Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
val iosMain by getting {
dependsOn(commonMain)
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
}
}
and to avoid Compose targets '[uikit]' are experimental and may have bugs! Error add this in gradle.properties
org.jetbrains.compose.experimental.uikit.enabled=true
Sync now !
Inside your shared module
commonMain directory create your first Composable function to use it for Android and IOS
@Composable
internal fun App(){
Text(Greeting().greet())
}
In your AndroidMain
make main.android
class to use your App function
@Composable
fun Application(){
App()
}
In your IosMain
make main.ios
class to use your App function
import androidx.compose.ui.window.ComposeUIViewController
fun MainViewController() = ComposeUIViewController { App() }
Now go to AndoroidApp
module to use the function we made in main.android class
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
Application()
}
Next go to IosApp
module to use the function we made in main.ios class
import shared // this important to import don't forget it!
@main
struct iOSApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
// inside your ContentView class
import SwiftUI
import shared
struct ComposeView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> UIViewController {
Main_iosKt.MainViewController()
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
}
struct ContentView: View {
var body: some View {
ComposeView()
.ignoresSafeArea(.keyboard) // Compose has own keyboard handler
}
}
Add this to solve dependencies conflicts in gradle.properties
kotlin.native.cacheKind=none
now you can run your android normally, for IOS
you need to run the following command first
./gradlew build
./gradlew :shared:linkPodDebugFrameworkIosSimulatorArm64
Now open iosApp.xcworkspace
inside xcode and run the app! or Run it inside Android Studio itself
Compose Mutliplatofrom Examples
Compose Mutliplatofrom Template
Happy Kotlin 🚀!