2023-03-23 12:44:18 +01:00
[![official project ](http://jb.gg/badges/official.svg )](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
[![License ](https://img.shields.io/badge/License-Apache_2.0-blue.svg )](https://opensource.org/licenses/Apache-2.0)
2023-04-05 16:32:37 +02:00
# Compose Multiplatform mobile application
2023-03-23 12:44:18 +01:00
2023-04-05 16:32:37 +02:00
> Compose Multiplatform is in Alpha. It may change incompatibly and require manual migration in the future.
You can use this template to start developing your own [Compose Multiplatform ](https://github.com/JetBrains/compose-multiplatform ) application.
The result will be a Kotlin Multiplatform project targeting Android and iOS.
2023-03-23 12:44:18 +01:00
2023-03-24 18:47:54 +01:00
![](readme_images/banner.png)
2023-04-05 16:32:37 +02:00
## Set up an environment
2023-03-23 12:44:18 +01:00
2023-04-05 16:32:37 +02:00
> **Important**. You will need a Mac with macOS to write and run iOS-specific code on simulated or real devices.
> This is an Apple requirement.
2023-03-23 12:44:18 +01:00
2023-04-05 16:32:37 +02:00
To work with this template, you need the following:
2023-03-23 12:44:18 +01:00
2023-04-05 16:32:37 +02:00
* A machine running a recent version of macOS
* [Xcode ](https://apps.apple.com/us/app/xcode/id497799835 )
* [Android Studio ](https://developer.android.com/studio )
* [Kotlin Multiplatform Mobile plugin ](https://plugins.jetbrains.com/plugin/14936-kotlin-multiplatform-mobile )
* [CocoaPods dependency manager ](https://kotlinlang.org/docs/native-cocoapods.html )
2023-03-23 12:44:18 +01:00
2023-04-05 16:32:37 +02:00
### Check your environment
2023-03-24 18:22:59 +01:00
2023-04-05 16:32:37 +02:00
Before you start, use the [KDoctor ](https://github.com/Kotlin/kdoctor ) tool to ensure you have all the tools and that your development environment is configured correctly.
2023-03-24 18:22:59 +01:00
2023-04-05 16:32:37 +02:00
1. Install KDoctor with [Homebrew ](https://brew.sh/ ):
2023-03-24 18:22:59 +01:00
2023-04-05 16:32:37 +02:00
```text
brew install kdoctor
```
2. Run KDoctor in your terminal:
```text
kdoctor
```
If everything is set up correctly, you'll see a valid output:
```text
2023-03-24 18:22:59 +01:00
Environment diagnose (to see all details, use -v option):
[✓] Operation System
[✓] Java
[✓] Android Studio
[✓] Xcode
[✓] Cocoapods
Conclusion:
✓ Your system is ready for Kotlin Multiplatform Mobile Development!
```
2023-04-05 16:32:37 +02:00
Otherwise, KDoctor will highlight which parts of your setup still need configuration and suggest how to fix them.
2023-03-24 18:22:59 +01:00
2023-04-05 16:32:37 +02:00
## Examine the project structure
2023-03-24 18:22:59 +01:00
2023-04-05 16:32:37 +02:00
1. Open the project in Android Studio.
2. Switch the project view from **Android** to **Project** to see all the files and targets belonging to the project.
2023-03-24 18:22:59 +01:00
2023-03-24 18:42:07 +01:00
< img src = "readme_images/open_project_view.png" height = "300px" >
2023-03-24 18:22:59 +01:00
Your Compose Multiplatform project includes three modules:
2023-04-05 16:32:37 +02:00
### shared
This is a Kotlin module that contains the logic common for both Android and iOS applications, the code you share between platforms.
This `shared` module is also where you write your Compose Multiplatform code.
You can find the shared root `@Composable` function for your app in `shared/src/commonMain/kotlin/App.kt` .
2023-03-24 18:22:59 +01:00
2023-04-05 16:32:37 +02:00
It uses Gradle as the build system. You can add dependencies and change settings in `shared/build.gradle.kts` .
The shared module builds into an Android library and an iOS framework.
2023-03-24 18:22:59 +01:00
2023-04-05 16:32:37 +02:00
### androidApp
2023-03-24 18:22:59 +01:00
2023-04-05 16:32:37 +02:00
This is a Kotlin module that builds into an Android application. It uses Gradle as the build system.
The `androidApp` module depends on and uses the shared module as a regular Android library.
2023-03-24 18:22:59 +01:00
2023-04-05 16:32:37 +02:00
### iosApp
2023-03-24 18:22:59 +01:00
2023-04-05 16:32:37 +02:00
This is an Xcode project that builds into an iOS application.
It depends on and uses the shared module as a CocoaPods dependency.
2023-03-24 18:22:59 +01:00
2023-04-05 16:32:37 +02:00
## Run your application
2023-03-24 18:22:59 +01:00
2023-04-05 16:32:37 +02:00
### On Android
2023-03-24 18:22:59 +01:00
To run your application on an Android emulator:
2023-04-05 16:32:37 +02:00
1. Create an [Android virtual device ](https://developer.android.com/studio/run/managing-avds#createavd ).
2. In the list of run configurations, select `androidApp` .
3. Choose your virtual device and click **Run** .
2023-03-24 18:22:59 +01:00
2023-03-24 18:43:11 +01:00
< img src = "readme_images/run_on_android.png" height = "60px" >
2023-03-24 18:42:07 +01:00
< img src = "readme_images/android_app_running.png" height = "200px" >
2023-03-24 18:29:30 +01:00
2023-03-24 18:22:59 +01:00
< details >
2023-04-05 16:32:37 +02:00
< summary > Alternatively, use Gradle< / summary >
2023-03-24 18:22:59 +01:00
2023-04-05 16:32:37 +02:00
To install an Android application on a real device Android device or an emulator, run `./gradlew installDebug` in the terminal.
2023-03-24 18:22:59 +01:00
< / details >
2023-04-05 16:32:37 +02:00
### On iOS
2023-03-23 12:44:18 +01:00
2023-04-05 16:32:37 +02:00
#### Running on an iOS simulator
2023-03-23 12:44:18 +01:00
2023-04-05 16:32:37 +02:00
Once you have configured your environment correctly,
you can select which iOS simulator to run your application in Android Studio by modifying the `iosApp` run configuration.
2023-03-23 12:44:18 +01:00
2023-04-05 16:32:37 +02:00
In the list of run configurations, select **Edit Configurations** and navigate to **iOS Application** | **iosApp** .
In the **Execution target** list, select your target device.
2023-03-23 12:44:18 +01:00
2023-03-24 18:43:59 +01:00
< img src = "readme_images/edit_run_config.png" height = "200px" >
2023-03-24 18:42:07 +01:00
< img src = "readme_images/target_device.png" >
2023-03-24 18:22:59 +01:00
2023-04-05 16:32:37 +02:00
Press the **Run** button to run your Compose Multiplatform app on the iOS simulator.
2023-03-24 18:22:59 +01:00
2023-03-24 18:42:07 +01:00
< img src = "readme_images/hello_world_ios.png" height = "200px" >
2023-03-24 18:22:59 +01:00
2023-04-05 16:32:37 +02:00
#### Running on a real iOS device
2023-03-23 12:44:18 +01:00
2023-04-05 16:32:37 +02:00
You can run your Compose Multiplatform application on a real device. To do that, you'll need the following:
2023-03-23 12:44:18 +01:00
2023-04-05 16:32:37 +02:00
* `TEAM_ID` associated with your [Apple ID ](https://support.apple.com/en-us/HT204316 )
* The iOS device registered in Xcode
2023-03-23 12:44:18 +01:00
2023-04-05 16:32:37 +02:00
Before you continue, we suggest creating a simple "Hello, world!" project in Xcode to ensure you can successfully run apps on your device.
You can follow the instructions below or watch this [this Standford CS193P lecture recording ](https://youtu.be/bqu6BquVi2M?start=716&end=1399 ).
2023-03-23 12:44:18 +01:00
2023-04-05 16:32:37 +02:00
< details >
< summary > How to create and run a simple project in Xcode< / summary >
1. On the Xcode welcome screen, select **Create a new project in Xcode** .
2. On the **iOS** tab, choose the **App** template. Click **Next** .
3. Specify the product name and keep other settings default. Click **Next** .
4. Select where to store the project on your computer and click **Create** . You'll see an app that displays "Hello, world!" on the device screen.
5. At the top of your Xcode screen, click on a device name near the **Run** button.
6. Plug in your device to the computer. You'll see this device in the list of run options.
7. Choose your device and click **Run** .
< / details >
##### Finding your Team ID
In the terminal, run `kdoctor --team-ids` to find your Team ID.
KDoctor will list all Team IDs currently configured on your system, for example:
```text
2023-03-24 18:22:59 +01:00
3ABC246XYZ (Max Sample)
ZABCW6SXYZ (SampleTech Inc.)
2023-03-23 12:44:18 +01:00
```
< details >
2023-03-24 18:22:59 +01:00
< summary > Alternative way of finding your Team ID< / summary >
2023-03-23 12:44:18 +01:00
2023-04-05 16:32:37 +02:00
If KDoctor doesn't work for you, try this alternative method:
1. In Android Studio, run the `iosApp` configuration with the selected real device. The build should fail.
2. Go to Xcode and select **Open a project or file** .
3. Navigate to the `iosApp/iosApp.xcworkspace` file of your project.
4. In the left menu, select `iosApp` .
5. Navigate to **Signing & Capabilities** .
6. In the **Team** list, select your personal team.
If you haven't set up your team yet, use the **Add account** option and follow the steps.
2023-03-23 12:44:18 +01:00
< / details >
2023-04-05 16:32:37 +02:00
To run the application, set the `TEAM_ID` associated with your Apple ID:
2023-03-24 18:22:59 +01:00
2023-04-05 16:32:37 +02:00
1. In the template, navigate to the `iosApp/Configuration/Config.xcconfig` file.
2. Set your `TEAM_ID` .
3. Re-open the project in Android Studio. It should show the registered iOS device in the `iosApp` run configuration.
2023-03-23 12:44:18 +01:00
2023-04-05 16:32:37 +02:00
## Make your first changes
2023-03-23 12:44:18 +01:00
2023-04-05 16:32:37 +02:00
In Android Studio, navigate to the `shared/src/commonMain/kotlin/App.kt` file.
It's the common entry point for your Compose Multiplatform app.
Here, you see the code responsible for rendering the "Hello, World!" button and the animated Compose Multiplatform logo:
2023-03-23 12:44:18 +01:00
2023-03-24 18:22:59 +01:00
```kotlin
2023-03-31 19:55:08 +02:00
@OptIn (ExperimentalResourceApi::class)
2023-03-24 18:22:59 +01:00
@Composable
internal fun App() {
MaterialTheme {
2023-03-31 19:55:08 +02:00
var greetingText by remember { mutableStateOf("Hello, World!") }
var showImage by remember { mutableStateOf(false) }
Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
Button(onClick = {
greetingText = "Hello, ${getPlatformName()}"
showImage = !showImage
}) {
Text(greetingText)
}
AnimatedVisibility(showImage) {
Image(
painterResource("compose-multiplatform.xml"),
null
)
}
2023-03-24 18:22:59 +01:00
}
}
}
```
Update the shared code by adding a text field that will update the name displayed on the button:
2023-03-31 19:55:08 +02:00
```diff
@OptIn (ExperimentalResourceApi::class)
2023-03-24 18:22:59 +01:00
@Composable
internal fun App() {
MaterialTheme {
2023-03-31 19:55:08 +02:00
var greetingText by remember { mutableStateOf("Hello, World!") }
var showImage by remember { mutableStateOf(false) }
Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
2023-03-24 18:22:59 +01:00
Button(onClick = {
2023-03-31 19:55:08 +02:00
greetingText = "Hello, ${getPlatformName()}"
showImage = !showImage
2023-03-24 18:22:59 +01:00
}) {
2023-03-31 19:55:08 +02:00
Text(greetingText)
}
+ TextField(greetingText, onValueChange = { greetingText = it })
AnimatedVisibility(showImage) {
Image(
painterResource("compose-multiplatform.xml"),
null
)
2023-03-24 18:22:59 +01:00
}
}
}
}
```
2023-04-05 16:32:37 +02:00
You'll see this change reflected on both the Android and iOS apps:
2023-03-24 18:42:07 +01:00
< img src = "readme_images/text_field_added.png" height = "200px" >
2023-03-23 12:44:18 +01:00
2023-04-05 16:32:37 +02:00
## How to configure the iOS application
You can further configure the basic properties of your iOS app using this template without opening Xcode.
In Android Studio, navigate to the `iosApp/Configuration/Config.xcconfig` configuration file. It contains:
* `APP_NAME` , a target executable and an application bundle name
* `BUNDLE_ID` that [uniquely identifies the app throughout the system ](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleidentifier#discussion )
* `TEAM_ID` , [a unique identifier generated by Apple that's assigned to your team ](https://developer.apple.com/help/account/manage-your-team/locate-your-team-id/#:~:text=A%20Team%20ID%20is%20a,developer%20in%20App%20Store%20Connect )
2023-03-23 12:44:18 +01:00
2023-04-05 16:32:37 +02:00
To configure the `APP_NAME` option, open `Config.xcconfig` in any text editor *before opening* the project in Android Studio, and set the desired name.
2023-03-23 12:44:18 +01:00
2023-04-05 16:32:37 +02:00
If you need to change this option after you open the project in Android Studio, do the following:
2023-03-23 12:44:18 +01:00
2023-04-05 16:32:37 +02:00
1. Close the project in Android Studio.
2. Run `./cleanup.sh` in your terminal.
3. Change the setting.
4. Open the project in Android Studio again.
2023-03-23 12:44:18 +01:00
2023-04-05 16:32:37 +02:00
To configure advanced settings, use Xcode. After opening the project in Android Studio,
go to Xcode and open the `iosApp/iosApp.xcworkspace` file, and make changes.