KMMBridge With SKIE Template

KMMBridge With SKIE Template

This is the documentation reference for our template project using KMMBridge and SKIE. You can find the project here:

touchlab/KMMBridgeSKIETemplate

This project provides a great base to start from for teams looking to publish Kotlin Multiplatform code to both Android and iOS.

Overview

The template project is designed to get you up and running quickly. If you are using GitHub, and are OK runnind GitHub Actions CI and using GitHub Packages for publication, this template will allow you to start publishing builds in minutes.

If you are already familiar with KMMBridge, this template is the spiritual successor to our original Kick Start project. The design of KMMBridge has changed significantly, so we decided to launch a new template sample and deprecate the rest.

Before You Start…

The rest of this doc is going to explain the repo and some parts of config. Our launch blog post is really the place to start to understand what KMMBridge is, who needs it, and why.

Read the blog post first!


The Project

The project is a template starting point for teams that want to publish Kotlin Multiplatform (KMP) code for native mobile development. Getting started with KMP in a production project can be difficult as there are multiple different systems that need to be configured. This project can be used directly as a template to start with, or as a reference for adding KMP to your specific environment.

The KMP tooling and documentation largely focus on local development. All of the code is in a monorepo, there’s one big module, and everybody builds locally. This works in some contexts, but absolutely does not in others. Some examples of where a different solution is needed:

  • Existing team trying KMP. This template is ideal to “test drive” KMP. You can publish binaries to your private GitHub for both Android and iOS. Experimenting with KMP will take little time or risk.
  • Existing project in multiple repos. No need to convert to a monorepo or use git submodules.
  • Larger team. Most larger teams modularize code already. KMP would be no different.
  • Publishing SDKs. Both internally and externally.

The project also uses SKIE, our new tool for producing better Swift-facing APIs from Kotlin.

Our post series about these tools and this release have much more detail about how you can use this project.

Structure

This repository is split into the following modules:

  • allshared only exists for iOS. It can have some iOS-specific source code, but also serves as the umbrella module for Xcode Framework publication. This is where both SKIE and KMMBridge are configured and run from.
  • analytics is a module to make typed analytics calls. The idea is that you write typed methods in shared code, and delegate to each platform’s analytics library. This helps keep analytics calls the same across platforms. These kinds of modules are a common place for teams to start experimenting with KMP.
  • breeds is a model of a more complicated feature. The code is based on KaMPKit. It’s structured around a BreedRepository which is able to list dog breeds and mark them as favorites. Data is stored in SqlDelight, and exposed to Android and iOS as Coroutines Flow instances.

The Android repository consumes breeds amd analytics as separate modules, while the iOS repository consumes the allshared module via the published framework.

Usage

  1. Use this Template Repo to Create Your Kotlin Repo

Click “Use Template”, give your repo a name, and create it.

  1. Edit GROUP

THIS IS A CRITICAL STEP In gradle.properties, edit the GROUP property and give it a value that corresponds to your project or org. If you attempt to publish with the same GROUP value, GitHub Packages may have conflicts.

GROUP=com.example.ourkmpproject
  1. Publish A Build

After the repo has been created and GROUP has been specified, make sure your change is committed and has been pushed to your repo. Then, in a browser, open the repo, go to “Actions”, and run one of the available CI workflows.

  • All Publish will publish both Android and iOS.
  • iOS Publish will only publish iOS.

Test Apps

There are 2 test apps in the repo. One for Android and one for iOS. Both apps will build and run locally. They should be used to make changes to the Kotlin code. Once those changes are complete, you can publish builds for outside consumers.

SDK Initialization

Both platforms have a single entry point that will return a “handle” to initialized modules from the shared code. How you would design your apps is, of course, up to you, but you’ll generally need to give shared code some startup context on either platform, and a single entry point often makes that simpler.

Android

Initialize the SDK in onCreate of your main Application instance by calling:

val sdkHandle = startSDK(analytics = AnalyticsImpl, context = this)

The analytics argument is an implementation of the Analytics interface defined in the Kotlin code. This allows your outside code to inject whatever analytics implementation you need. iOS will need a similar implementation.

The returned SDKHandle has a reference to BreedRepository, AppAnalytics, and BreedAnalytics. These are all relatively simple singletons that you can make available to your other code.

iOS

Import the allshared module

import allshared

Initialize the SDK somewhere central as the application is starting up.

init() {
    self.handle = StartSDKKt.startSDK(analytics: IosAnalytics())
    handle.appAnalytics.appStarted()
}

Similar to Android, you’ll need to pass in an implementation of the Analytics interface.

Basic Design

The BreedRepository exposes data and app state as Flow instances. You can interact with it through suspend functions. Earlier versions of this template project would wrap BreedRepository to provide callbacks to bridge the Flow instances. SKIE exposes Flow instances as proper AsyncSequence instances to Swift, and does not put any restrictions on suspend functions.

That means writing shared Kotlin code is much easier, as you can build modern Kotlin APIs without needing to wrap the code or avoid structures like sealed classes.

Check out our post series to better understand how KMMBridge and SKIE together will make using KMP in an iOS environment a much better experience.