Testing a Shared KMM Repo Locally
There’s a lot of different ways of organizing your Kotlin Multiplatform Mobile codebase, Ben Asher and I gave an overview of some of those at KotlinConf 2019, where I described a setup where the shared code lives in your iOS and Android codebase and is copied between them. The pro of this was an easy local development setup, but there are a lot of cons. We moved away from this style to a separate (third) repository for the multiplatform code last year.
The general model for working in this new third repository is:
- Write shared code in the repository with unit tests.
- Publish a local version of the artifact (.jar for Android, .framework for iOS)
- Use that published local artifact in the Android and iOS apps to develop your feature
- Once those are good to go, open a PR on the multiplatform repo
- Push a release version of the multiplatform
- Open a PR on the Android/iOS repos with the integrated change.
There’s lots of room for optimization here, but this post will focus on steps 2/3. Ideally we want to get back the ease of having the multiplatform code live in the app repos, and thankfully there are mechanisms to do just that both in Gradle and CocoaPods.
Android
Consider this Gradle module in an Android repo which uses your multiplatform codebase:
|
|
If you have the mobile multiplatform repository checked out locally, you can just use that local
copy directly using Gradle composite builds.
In your settings.gradle
:
|
|
Now instead of downloading and using a maven artifact, it will build the included project and then use the Gradle subproject specified. Now you can make changes in your local copy of the multiplatform repo and see them reflected immediately.
iOS
Our iOS setup uses CocoaPods which enables local development. Kotlin comes bundled with a CocoaPods integration you can apply to get things working.
In your multiplatform Gradle project:
|
|
Applying the CocoaPods plugin also automatically configures some framework binaries. In our case we were creating those manually so instead we had to switch to configure the ones CocoaPods made.
|
|
Finally you will want to generate the .podspec
, which you can do by running ./gradlew :my-module:podspec
.
The output may need to be manually changed to adhere to your published artifact’s naming; in our case
the generated .podspec
referred to the module name umbrella
where we instead want it to use
the framework name CashKt
, so we had to rename from umbrella.podspec
to CashKt.podspec
and change
the spec.name
property inside as well.
Now in your actual iOS repository you can swap out this line of code in Podfile
:
|
|
To this:
|
|
And running the iOS app will first build your local version of the multiplatform code and then run it. Yay!