KMMBridge

KMMBridge - XCFramework publishing for Kotlin Multiplatform

KMMBridge is a Gradle plugin that allows you to publish Xcode XCFrameworks from your Kotlin Multiplatform projects. Developers using Xcode can then directly consume these XCFrameworks using Swift Package Manager (SPM) or CocoaPods.

KMMBridge can be used to publish your iOS KMP builds to public or private repos, using various backend options to host the binary XCFramework files.

General Use Cases

Piloting KMP

When introducing KMP to existing mobile teams, providing a versioned XCFramework introduces very little friction for the iOS developers. You can publish KMP code and use it in your builds quickly and easily. The XCFramework is a compiled binary, so no extra Gradle/KMP tooling is required.

Publishing SDKs

Whether internal or “public”, KMMBridge can be configured to publish SDKs for your users. For CocoaPods, that includes the ability to publish to the CocoaPods Master Repo, where they host the config for public CocoaPods libraries.

Quick Start

Configuring any production publication from scratch can be difficult. However, if you are using GitHub and looking to publish only for SPM, we have a quick-start option that will get you up and running in minutes.

SPM Quick Start

Publishing Overview

To make Kotlin code available to Xcode and/or Swift build targets, the Kotlin KMP compiler builds an Xcode Framework. Regardless of the method by which you include that Framework, that is how Kotlin code is made available to Xcode.

All out-of-the-box build configurations for KMP are locally integrated. That means, to call KMP from Xcode, you need to locally build your Kotlin code.

Kotlin compiler builds an Xcode framework

However, you can assemble and publish these same builds for others to use directly. That is what KMMBrdige does. The broad steps are:

  • In CI, the Kotlin compiler builds an Xcode Framework from KMP source
  • The Framework outputs are converted to XCFramework packages, then all architectures are zipped in one file
  • The binary file is uploaded to some cloud host (GitHub Packages/Releases, AWS S3, Maven Repo, etc)
  • The Package.swift file is updated in the KMP repo
  • Xcode accesses the Kotlin build through SPM. It gets the Package.swift file from git, and the Kotlin XCFramework from the cloud host

Publish XCFramework with SPM

Publishing for CocoaPods is possible with KMMBridge as well. The binary XCFramework is published in the same way. In fact, if you publish both SPM and CocoaPods, they’ll both use the same published binary. CocoaPods needs to publish it’s package metadata, a “podspec” file, to a separate repo whose only purpose is to host podspec files.

Publish XCFramework with CocoaPods

CocoaPods publishing is more complex because it involves multiple repos, and CocoaPods attempts to integrate and build your framework before publishing, which can result in failures that would otherwise be “fine” in your app. As SPM has grown in popularity, requests for CocoaPods have become significantly less frequent. As a result, most of our newer tutorials focus on SPM.

KMMBridge Setup Overview

To use KMMBridge, you’ll need the following:

  1. A KMP module configured to build some Xcode Frameworks that you want to publish (this is in your Gradle config).
  2. A DependencyManager implementation and it’s related configuration. The options are SPM and CocoaPods. You can use both at the same time if publishing to both.
  3. An ArtifactManager. This interface actually “publishes” the zip file to a remote server.
  4. Build and publication process. Generally a CI workflow. This is also your code. We provide starter templates, but CI generally winds up being custom over time.
  5. Xcode config to access both the dependency config file and the zip file. Access to the config file and the binary zip is configured separately in Xocde.

Swift Package Manager (SPM)

Most teams seem to be using SPM, and will be getting the most focus in our tutorials and docs.

kmmbridge {
    spm()
    // Other config, including the artifact manager
}

See the SPM Docs for details.

CocoaPods

CocoaPods has been around for much longer, and is in some ways more flexible than SPM. However, a CocoaPods publishing configuration requires multiple repos, and is generally more complex than SPM.

kmmbridge {
    cocoapods("git@github.com:yourorg/YourPodspecRepo.git")
    // Other config, including the artifact manager
}

See the CocoaPods Docs for more information.

Binary Artifacts

When publishing XCFrameworks, the Kotlin compiler creates a Framework for each target architecture. Each Framework is then converted to an XCFramework. All of these are then bundled into a single zip file.

That zip file needs to be hosted somewhere that is accessible by a stable URL.

If that URL is intended to be private, it needs to provide access through basic authentication. Services like AWS S3 do not provide basic authentication by default. You would need to create some kind of server, or find a service, that will provide private access to these resources. For a detailed post about the auth complexities involved (for Google Cloud, but its the same problem) see Nate Ebel’s post on SPM publishing

Options provided by KMMBridge:

You can implement a custom artifact location by implementing ArtifactManager.

Don’t commit binaries to git

It is possible to commit your binary builds directly to git. However, Xcode needs to pull your repo to access both config info and the binary itself. Somewhere around 5 gigs, this gets really slow. Non-trivial KMP binaries are 50-100 megs each (in dev, not on the phone). This will be a problem before long, and best avoided at the beginning.

Xcode Configuration

To access your frameworks from Xcode using SPM, if they are not public, you need to configure authentication in two places. This is a very common source of confusion. These are the places:

  • Xcode GUI. Give it access to your git repo where your config is stored.
  • ~/.netrc. This file is accessed by curl to actually download your zip binary. This file is the one that needs basic authentication to function.

See iOS Dev Setup for more info.

GitHub always requires auth

GitHub requires authentication to download binary files, even for public repos. If you publish to a public repo and store your files in either GitHub Packages or GitHub Releases, you still need to configure ~/.netrc

Reach Out

For help, discussions, issues, etc, Reach Out