Writing a Multi-Platform App using Kotlin Multi Platform + Compose Multi Platform

Writing a Multi-Platform App using Kotlin Multi Platform + Compose Multi Platform

Create an Android and iOS application using the same code.

·

4 min read

For quite some time, I have wanted to build native apps. But it seemed that native apps were the luxury of big companies who could afford to build iOS + Android + web, while I could only afford to build on one platform. That generally meant web - because you get the other 2 largely for free (with some investment in responsive design).

But web apps are not as sticky. You typically have to remember some url to visit, they take a second or 2 to pull up (and by then your user has already started 4 other tasks), and they have more chrome. Small differences, and web was still the best bet...but in 2024 shouldn't we be able to have the speed of unified development and the quality of native apps?

That is what lead me to Kotlin Multi Platform and Compose Multi Platform. TLDR: I think this may be the path. Follow along as I quickly rip through building a tiny little Android app and converting it to a multi platform Android and iOS app in the post.

Let's Get Multi Platform Tools

First, there is about 8 GB of tools that you need to install (7 GB being iOS simluators). I found this post from Jetbrains super helpful - just walk through it and come back here.

https://www.jetbrains.com/help/kotlin-multiplatform-dev/multiplatform-setup.html#install-the-necessary-tools

  • I could not get cocoapods to install on my machine - and it is not necessary to start.

Let's get Scaffolding

Visit the Kotlin Multiplatform New Project Wizard

  • This is a little confusing, but if you select "Share UI (with Compose Multiplatform UI framework)" (aka, you do not select "Do not share UI (use only SwiftUI)") you will NOT end up with a Shared folder.

  • Alternatively, if you select Do not share UI then you end up with a Shared folder.

At this point, you should have some mini application that makes an image float down when you click a button - meh. Now it is time to change the world: create an application that allows golfers to quickly figure out which holes they "bump" on (get an advantage on) based on their handicaps.

Start with a Standard Android App

If you do not have an Android app, you can start with a toy app at https://github.com/dyor/bumps/ (it calculates which scores a golfer will "bump" on based on their handicaps). This snapshot is prior to any multi-platform changes were made.

Extract Code Into the Scaffolding Created Above

Start with some changes in App.kt (composeApp > src > commonMain > Kotlin [commonMain] > App.kt). This step feels a bit like magic - but you can basically comment out what is within the MaterialTheme and replace it with a call to AppContent. And everything...just works.

As a little housekeeping, I moved the Golfer and Hole data classes into their own files, as well as the BumpCalculator logic.

Make the Design...Amazing

I made some adjustments to the layout so that there was a bit of padding, and I have it so that it shows a bit more information (e.g., as you are adding golfers, it generates a list; on the bump matrix, it shows the difficulty of each hole and the bumps for each golfer). Each of the changes I made worked perfectly for Android and iOS - one code base to rule them all! You can see the final code here https://github.com/dyor/bump-multiplatform

Conclusion

I am bullish about Kotlin Multiplatform and Compose Multiplatform. You can write your app once and have it available on both iOS and Android - both with native experiences. I have not tested some of the things where I would expect there to be some variances - such as API or database interactions - the subject of a future blog post. I would love to hear your experiences - add a comment below.

Some Things I Missed

Although the posts and instructions above worked pretty well for me, there were a couple of places I got tripped up. Hopefully this will speed up your troubleshooting if you fall into the same holes.

  • Install the Kotlin Multiplatform Mobile plugin in Android Studio

If you get an error message "Error: Selected device not found" when you try to build to iOS, this may be because you have not installed the iOS simulators yet. Head over to Xcode and "Help > Open Developer Tool > Simulator" and download the iOS simulator. This is a monster download - 7GB - so give it some time!

BUILD FAILED

The following build commands failed: PhaseScriptExecution Compile\ Kotlin\ Framework /Users/mattdyor/Downloads/KMP/build/ios/iosApp.build/Debug-iphonesimulator/iosApp.build/Script-F36B1CEA2AD836FC00CB74D5.sh (in target 'iosApp' from project 'iosApp') (1 failure) - it was a problem with Gradle - went to Andriod Studio > Settings > Build, Execution, Deployment > Build Tools > Gradle, and then I selected a newer version of Gradle JDK.

When you first try to push to a physical iPhone, you need to physically connect the iPhone to your Mac. Also, if you have not done so, you will need to add a team account, or you will get an error saying that your iosApp needs a development team.