Chapters

Hide chapters

Kotlin Multiplatform by Tutorials

Third Edition · Android 15, iOS 18, Desktop · Kotlin 2.1.20 · Android Studio Meerkat

C. Appendix C: Sharing Your Compose UI Across Multiple Platforms
Written by Carlos Mota

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

Throughout this book, you’ve learned how to share your business logic across Android, iOS and desktop apps. What if you could go a step further and also share your Compose UI?

That’s right — along with Kotlin Multiplatform, you now have Compose Multiplatform, which allows you to share your Compose UI with Android, iOS and desktop apps.

Note: This appendix uses learn, the project you built in chapters 11 through 14.

Setting Up an iOS App to Use Compose Multiplatform

To follow along with the code examples throughout this appendix, download the project and open 17-appendix-c-sharing-your-compose-ui-across-multiple-platforms/projects/starter with Android Studio.

starter is the challenge 1 version of learn from Chapter 14 with the only difference that the shared modules are included as projects and not published dependencies. It contains the base of the project that you’ll build here, and final gives you something to compare your code with when you’re done.

With the latest version of Compose Multiplatform, it’s possible to share your UI with multiple platforms. In this appendix, you’ll learn how to do it for Android, Desktop and iOS apps.

Although, you can find alternative solutions to create an iOS app with Compose Multiplatform, the one that you’re going to use in this section is the one suggested by JetBrains, which uses the Kotlin Multiplatform Wizard, created and maintained by them.

Start by opening the wizard and define:

  • Project Name: learn
  • Project ID: com.kodeco.learn

Confirm that you have the Android, iOS (with the share UI setting on), and Desktop targets selected, then click DOWNLOAD.

Extract the content from the .zip file. Open the template, and you’ll find a folder named iosApp, where you’ll find the skeleton for building your iOS app with Compose Multiplatform. Copy it to the root folder of learn and when pasting it rename it to iosAppCompose.

Note: Since the template might change in the future, you can find the current version of it as compose-multiplatform-template in the project folder.

Your project structure should now be similar to this one:

Fig. B.1 — Project view hierarchy
Fig. B.1 — Project view hierarchy

Open the iosApp.xcodeproj file located on iosAppCompose with Xcode. Before diving-in into sharing the UI between all the platforms, let’s customize the project first.

Open ContentView.swift. Here is the entry point for the (Compose) screen to be loaded. It’s done via the makeUIViewController function, in this template, which internally calls MainViewControllerKt.MainViewController(). You’ll create this implementation later in the chapter. For now, replace it with UIViewController() and remove import ComposeApp, so you can compile the project. This ComposeApp framework is the shared UI that you’re going to configure.

Open iosApp (the root folder) and go to BuildPhases. Here, you’ve got a Compile Kotlin run script that’s referencing, by default, the shared module and generating a framework which will be included in the app. This is the same approach that we initially started with learn iosApp at the beginning of “Chapter 11 – Serialization”.

Since, you haven’t created the shared UI module, comment the embedAndSignAppleFrameworkForXcode task for now:

#./gradlew :composeApp:embedAndSignAppleFrameworkForXcode

Compile the project. You should see an empty screen similar to this one:

Fig. B.2 — iOS App
Fig. B.2 — iOS App

Depending on the current version of Java that you have set as your JAVA_HOME you might see an error similar to the following:

‘compileJava’ task (current target is 17) and ‘compileKotlin’ task (current target is 18) jvm target compatibility should be set to the same Java version.

This happens because the Terminal where your script is running has a different version than the one that’s built in with Android Studio. You can change your JAVA_HOME to reflect the same directory, or you can just add the following before any instruction in the Compile Kotlin run script:

export JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home/"

Make sure the path in the command above matches your version of Android Studion. For instance, if you’re using the Preview version, you’ll need to change the directory to Android Studio Preview.app.

As you might have noticed, this new iOS app is using the template values for the icon and bundleId. Let’s update them to use the same one’s that were already defined for learn iosApp. Open the Config.xcconfig file located inside the Configuration folder and replace the existing content with:

TEAM_ID=
BUNDLE_ID=com.kodeco.learn
APP_NAME=learn

If you now go to iosApp and click on the General section and look for the Bundle Identifier setting, which is under Identity, you’ll see that both the app name and bundle ID were updated to learn and com.kodeco.learn respectively.

Finally, open Assets and remove the existing AppIcon. Open Finder and navigate to iosApp/iosApp/Assets.xcassets and copy the existing AppIcon.appiconset folder to iosAppCompose/iosApp/Assets.xcassets. Return to Xcode, and you should now see the Kodeco logo in AppIcon.

To confirm that your iOS app is ready, compile the project. You’re going to still see an empty screen, but if you now minimize your app, the name and icon are correct. :]

Fig. B.3 — iOS App icon
Fig. B.3 — iOS App icon

Updating Your Project Structure

To share your UI, you’ll need to create a new Kotlin Multiplatform module. This is required because different platforms have different specifications — which means you’ll need to write some platform-specific code. This is similar to what you’ve done throughout this book.

Xeh. X.6 — Bsahuvz vioj puosebrgl
Rap. N.2 — Gcuwabr mioc loijaggns

Sharing Your UI Code

Although the code of both platforms is quite similar, the Android app uses platform-specific libraries. Since the UI needs to be supported on both, there are a couple of changes required.

Migrating Your Android UI Code to Multiplatform

Start by moving all the directories inside androidApp/ui into shared-ui/commonMain/ui. Don’t move the MainActivity.kt file, since activities are Android-specific.

Compose Multiplatform

Jetpack Compose was initially introduced for Android as the new UI toolkit where one could finally leave the XML declarations and the findViewById calls behind and shift towards a new paradigm – declarative UI.

Menkepi Ezonapoad Pexpame Sofihoim 5 Muvwehu Hipuvour Xekduno Zeaysuwuim Gegquqe EE Zagpega Haqraxeg Qoxquti Bovxeda Luqriti EO Buoxbil (Ocgxiig)
Fit. W.9 — Pobsanr Luplace coqs-jofoh yaasneb

Migrating to Compose Multiplatform

Open the BookmarkContent.kt file from shared-ui. Here you’ll see that the imports to androidx.compose* are not being resolved.

Updating Your Shared UI Dependencies

Now that shared-ui contains your app UI, it’s time to add the missing libraries. Open the build.gradle.kts file from this module and look for commonMain/dependencies. Update it to include:

Migrating Your UI Components

Not all classes in an Android Compose project are available in Compose Multiplatform. Sometimes, they are in different packages, other times they have different names, and occasionally, you need to use a third-party library or implement them yourself. In HorizontalPagerIndicator.kt file, you’ll encounter all three scenarios.

Using Third-Party Libraries

Although Compose Multiplatform is taking its first steps, the community is following closely, releasing libraries that help make the bridge between Android and desktop apps.

Fetching Images

There are currently two libraries commonly used to fetch images in Compose Multiplatform:

Using LiveData and ViewModels

learn was built using LiveData and ViewModels that are available in Android through the runtime-livedata library. Since it contains Android-specific code, you cannot use the same library in the desktop app.

Handling Navigation

There are multiple libraries that handle navigation between different screens. In previous editions of this book, you used precompose.

Handling Resources

All platforms handle resources quite differently. Android creates an R class during build time that references all the files located under the res folder: drawables, strings, colors, etc. Although this gives you easy access to the application resource files, it won’t work on other platforms.

Configuring moko-resources

Start by opening libs.versions.toml file, located inside the gradle folder. Inside the [versions] section add the latest moko-resources version:

Loading Local Images

You’ll write the logic to load local images in Kotlin Multiplatform. This is necessary since Android uses the R class to reference images, which doesn’t exist on other platforms.

Using Custom Fonts

The font that the three apps use is OpenSans. Since each one of the platforms has its default, you’ll need to configure a custom one. You’ll use, once again, moko-resources to load the new font.

Sharing Strings

Once again, you’re going to use the moko-resouces library to share strings across all platforms.

What’s Missing?

With all of these changes done, you’re almost done. Open the desktopApp project and:

Fap. T.7 — Caol im Ocmnaiq Iys
Man. L.7 — Siem ig Ohgbeaw Uxp

Vuy. J.0 — Tuok ay Gewhlim Uzp
Lad. F.5 — Miiv oz Fugwpis Old

Liy. R.2 — Jiis uz iUG Oml (hosv jogu)
Raj. N.7 — Pioz al uET Urs (xisq bexo)

Wic. L.3 — Yiod eb oIV Akb (ladvj qoja)
Jan. P.1 — Guuj ac uOB Asl (firhz kaqe)

Where to Go From Here?

Congratulations! You just finished Kotlin Multiplatform by Tutorials. What a ride! Throughout this book, you learned how to share an app’s business logic with different platforms: Android, iOS and desktop.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2026 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now