KMMBridge and SKIE: The Template Project Overview

· 6 min read

Back when we launched KMMBridge, we put out a post and template application: Quick Start with KMMBridge - 1 hour tutorial. This series of posts will update that template project across several dimensions. Before diving into each, let’s walk through the sample and what it does.

touchlab/KMMBridgeKickStartSKIE

Cloning and Setup

If you don’t plan to code along with the post, you can skip this section.

Dev Environment

You’ll want to make sure your KMP and native mobile dev environment is ready for building and running the sample app.

  • Kotlin IDE: Android Studio or Intellij. Newer Android projects can have issues with Intellij, so use Android Studio if you run into issues.
  • XCode: Ideally version 14.3.1
  • Java JDK 17

For more detail, see Set up an environment. Note, we recommend installing kdoctor to check your environment. We will be using SPM rather than Cocoapods for this tutorial, so you don’t need to install that (but we would recommend that you do).

Kotlin Project

Open the root folder of the cloned project with your Kotlin IDE. If you have issues importing, you’ll want to resolve those before moving forward.

Open gradle.properties and change GROUP=co.touchlab.kmmbridgekickstartskie to something else. It can be any valid group name, but make sure to keep it lower case, as GitHub packages can have issues with upper case. Also, if you leave it as is, GitHub Packages can have weird conflicts, so you really should change it to something eles :)

First Build

We are using SPM for this sample project. You can use Cocoapods instead if you want. KMMBridge can publish to either, and it doesn’t matter what your local dev tooling does.

The local SPM dev flow is less integrated than other methods, but still relatively simple to use. See SPM Local Dev Flow from the KMMBridge docs for details. In summary, when you want to run your iOS test application, you need to run Gradle.

Open a terminal in the root project director and run the following:

./gradlew spmDevBuild -PspmBuildTargets=ios_simulator_arm64

If you are on an Intel mac, replace ios_simulator_arm64 with ios_x64.

Run iOS Test App

The goal of this project is to publish shared code libraries for other devs to include. However, we have test apps included for local testing of the module.

Open the iOS sample by going to ./testapps/ios and double-clicking ios.xcodeproj.

Select an iOS simulator and run the project.

iOS Code Folder

Check In

If you’re coding along, at this point the sample builds should have worked. If not, reach out.

Project Overview

The project is structured like an internally published SDK for a native mobile team to share code.

The design for an external SDK would not be dramatically different, and we will follow up with a post on what would likely be changed. Errors in external apps are more difficult to diagnose because you’ll rarely have access to error reports, and outside users are more likely to have setup and configuration issues. External SDKs need to be proportionally simpler, less likely to have errors, and have better error messages when they do.

Modules

There are 2 modules: breeds and analytics.

breeds is largely taken from our KaMP Kit reference project. It queries an api to get a list of dog breed names, and stores them in a local database. Through the repository class, you can “favorite” certain breeds. The goal of this module is to show how to use a shared data module, with some networking and concurrency code. The first features many teams try with KMP involve database storage and networking. breeds is a minimal example of doing that.

analytics provides several methods that client code can call to send analytics events. Analytics in mobile development can be difficult to get right. Not because it is complex, but because it is untyped, difficult to verify, and generally “not fun” to work on. Making an animation on a screen provides instant feedback and is fun to build. Passing strings to a function is less so. Each platform needs to code this, and needs to do it correctly. It’s very easy to miss an entry in a spreadsheet, get the case wrong, etc.

Building a typed analytics library is a common suggestion for KMP. Write a bunch of functions with correct types being passed in, and call the underlying analytics library in common code. This reduces copy/paste errors, and makes changes and additions much less likely to be missed on either platform.

For Android, both of these modules are published as aar packages and should be included separately. For iOS, there is one publication. Kotlin for iOS needs to build a single, large Xcode framework rather than one per module. That is a limitation of the platform. When including multiple modules from a single project, you should create an “umbrella” module to publish the Xcode framework.

allshared is the umbrella module that actually builds the Xcode Framework output. We’ll dive more into how this works later. Just know that this is where other modules are collected, it is where our Xcode publishing config is happening, and if you add more modules, they need to be added to the umbrella to be available to iOS.

testapps is not really a “module”. The test harness applications live in here. They aren’t designed as “samples”, but rather a place to test your shared library code before publishing. This is a useful pattern for KMP development, but is common in larger orgs spread across feature teams. Each major feature section will likely have a test harness app which will allow for faster and more focused development.

Publishing

The project is configured to be hosted and published to GitHub, using GitHub Actions for CI and GitHub Packages for artifact hosting. This is generally the simplest option, but if you are using different systems, KMMBridge can be extended to work in other contexts.

The basic flow of the project is to publish SDK versions with automatic versioning. There’s a base version in gradle.properties:

LIBRARY_VERSION=0.1

On each publish, a patch version is appended automatically, and a tag is added to the git repo. If the base version is changed, say to 0.2, the automatic version counting starts over.

This sample has a significant difference from the original KMMBridge Quick Start. The incremental versioning was only on the iOS side, as the original design of KMMBridge was focused on that alone. Teams using the KMMBridge Quick Start sample often wanted to publish both Android and iOS with the same patch versioning scheme. The numbering scheme was originally implemented in KMMBridge, but for Android, the version really needs to be set before Gradle starts. The versioning is now handled externally with GitHub Action scripts. We’ll publish an update about that soon as well.

Summary

You should now have a forked, cloned, functioning repo project. To include the published code in apps other than the test apps, follow the official KMMBridge instructions:

The next posts in the series will cover SPM-based development, which is currently lacking in the stock Kotlin tooling, API enhancement capabilities enabled by SKIE, mobile SDK publishing with KMP in general, and approaches for getting started in different scenarios.