Samples of Using KMMBridge
Tags: kotlin, android, ios, mobile
Published: 2022-11-30 20:46:11

## What is KMM Bridge?
KMMBridge is a Gradle plugin by Touchlab that aims to simplify the process of pushing a Kotlin Multiplatform SDK binary to a remote repo to allow iOS developers to use the shared SDK without installing the Kotlin toolchain or building the Kotlin code on every app build.

## What is this Sample?
This sample project showcases our typical project setup for adding Kotlin Multiplatform Mobile code to existing separate Android and iOS apps using KMMBridge. We keep the Android app and the shared code in the same repo and keep the code to an absolute minimum with no dependencies so the project will build faster to speed things up when playing around with custom publish config. To see how to set up a project that keeps the Android app in a separate repo and uses a more realistic structure in shared code, check out the article [Quickstart Guide to KMMBridge](https://touchlab.co/quick-start-with-kmmbridge-1-hour-tutorial/)

## Sample Repos 
The basic KMMBridge sample is split into four repos rather than being a monorepo to emulate the trend we've seen from teams adopting KMM into existing apps by publishing a KMM library from one repo for iOS apps in other repos to consume. 
The four repos are: 
- [KMMBridgeSampleKotlin](https://github.com/touchlab/KMMBridgeSampleKotlin) aka `Kotlin Repo` - This is the Kotlin repo with the shared SDK code as well as an Android app that uses it. 
- [KMMBridgeSampleCocoaPods](https://github.com/touchlab/KMMBridgeSampleCocoaPods) aka `CocoaPods Repo`- a repo that pulls down the sdk with CocoaPods to use in an iOS app
- [KMMBridgeSampleSpm](https://github.com/touchlab/KMMBridgeSampleCocoaPods) aka `SPM Repo` - a repo that pulls down the sdk with Swift Package Manager to use in an iOS app
- [PublicPodspecs](https://github.com/touchlab/PublicPodspecs) aka `Podspec Repo` - A CocoaPods custom Podspec repo. When publishing for CocoaPods a podspec file will be pushed to this repo in a folder with the version number. See the CocoaPods section for more info on this. 

## KMMBridgeSampleKotlin - The Kotlin Code
This repo demonstrates the usual first step for a larger team that wants to try out Kotlin Multiplatform: putting new or existing Kotlin code in a `shared` module in your Android app repo. This repo also has a standard Android `app` module
that depends on the shared code through a Gradle project dependency. 

The `shared` module is a Kotlin Multiplatform module and targets `android`, `ios`, and `iosSimulatorArm64`; declared in the `kotlin` block of the `build.gradle.kts`. 

In the `kmmbridge` config block, we set publishing both with both Swift Package Manager and Cocoapods. For your project you can just include one or the other based on your team's needs. It also uses `githubReleaseVersions` to autoincrement versions when publishing a framework. Look over [the docs](https://touchlab.github.io/KMMBridge/general/CONFIGURATION_OVERVIEW) for more configuration options.
```kotlin
addGithubPackagesRepository()
kmmbridge {
    mavenPublishArtifacts()
    githubReleaseVersions()
    spm()
    cocoapods("git@github.com:touchlab/PublicPodspecs.git")
    versionPrefix.set("0.6")
}
```

### Publishing Changes to Kotlin Code
Since this publishes frameworks to our GitHub org, you'll need to fork the repo in order to publish changes. If you're only 
using SPM and remove the CocoaPods publishing, this should be enough to start publishing your changes. If you want to use 
CocoaPods you'll also need to fork the [Podspec Repo](https://github.com/touchlab/PublicPodspecs) and change the URL passed to the `cocoapods(...)` config above to your repo. You'll also have to set up deploy keys as secrets in your KMM repo. [See Here](https://touchlab.github.io/KMMBridge/cocoapods/COCOAPODS_GITHUB_PODSPEC) for instructions on that.

Once these steps are done you should be able to publish a new version of the SDK by manually running the publish job by going to the `Actions` tab, selecting, `KMM Bridge Publish Release` and clicking `Run workflow`. 

![run workflow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fkhs02ire6fd1676cx6t.png)

## Using KMM Code from iOS 
### Configure Access
To pull down the binary and build your iOS app you'll need to configure authentication with GitHub Packages. This can either be done in your `~/.netrc` file or through Mac's Keychain Access.

Either way you'll need to generate a GitHub Personal Access Token (PAT) with repo access and `read:packages`.
![pataccess](https://tl-navigator-images.s3.us-east-1.amazonaws.com/docimages/2022-10-17_16-33-pataccess.png)

Once you get a PAT string from that, create or open `~/.netrc` and add this with your username and the PAT that was created: 
```shell
machine maven.pkg.github.com
  login [your username]
  password [your PAT]
```

If you want to use Mac's keychain to manage access, check out [this blog post](https://medium.com/geekculture/xcode-13-3-supports-spm-binary-dependency-in-private-github-release-8d60a47d5e45) for more details on setting that up.

### SPM
Since the base KMM repo is public, you should be able to clone [the spm sample repo](https://github.com/touchlab/KMMBridgeSampleSpm) and run it. When you build the app it will look at the `Package.swift` file in the root of the Kotlin module to get the url 
for the most recent version of the SDK then it will download the framework from that URL and include it in the project's build.

#### Getting Remote Changes
To get changes to the Kotlin code you made in your fork of the repo, you'll have to change the SPM dependency to that repo.
To do this first remove the existing dependency by selecting the project, clicking `Package Dependencies`, clicking the package, and hitting the minus button. 

![delete spm package](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/60x7ioqcgw8pv5wkx8g7.png)

Next, add your repo as a new dependency by clicking the plus button, pasting your repo URL in the search bar, and clicking 
`Add Package`. Double-check the version rules to make sure it will grab the version you want.

![add swift package](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kofi7d9r0ca53ffabxf3.png)

If you've already run the publish job in the Kotlin repo, SPM should pull the SDK in with your changes, assuming you selected the version correctly. If you publish a new version and want to pull it, you can right-click `shared` in the sidebar and click `Update Package` 
to pull in the most recent version. 

If you want to build the Kotlin code locally and test in the iOS app without publishing every change, check out [this document](https://touchlab.github.io/KMMBridge/spm/IOS_LOCAL_DEV_SPM) on the SPM local dev flow.

### Cocoapods
To run the CocoaPod based iOS app, clone [the sample repo](https://github.com/touchlab/KMMBridgeSampleCocoaPods.git) and 
run `pod install` in the root of the repo to download the SDK, then open the `xcworkspace` file and run the app. `pod install` will look in https://github.com/touchlab/PublicPodspecs for a podspec matching the version specified in the `Podfile` and 
download the framework it points to. 

#### Getting Remote Changes
To pull in changes you made to the Kotlin code with CocoaPods, you'll need to edit the `Podfile` to point to the Podspec repo 
you created. Then run `pod update` again and reopen your workspace file. We use `~> 0.6.0` to tell CocoaPods to use the highest version above 0.6.0 up to but not including version 0.7.0. Since we set the version prefix to 0.6.0 in the `kmmbridge` config and automatic versioning, every publish will get a new patch version for CocoaPods to recognize.

```
source '<YOUR PODSPEC REPO>'

target 'KMMBridgeSampleCocoaPods' do
  if ENV.include?("LOCAL_KOTLIN_PATH")
    pod 'shared', :path => ENV["LOCAL_KOTLIN_PATH"]
  else
    pod 'shared', '~> 0.6.0'
  end
end
```

To build and test Kotlin changes locally with CocoaPods, check out [this doc](https://touchlab.github.io/KMMBridge/cocoapods/IOS_LOCAL_DEV_COCOAPODS)
on the CocoaPods local dev flow.

If you have questions, don’t hesitate to reach out! You can head over to [#touchlab-tools](https://kotlinlang.slack.com/archives/CTJB58X7X) on the kotlinlang Slack or fill out the [Contact Us](https://touchlab.co/contact-us/) form on the site. We look forward to hearing from you!