· 6 min read Posted by Kevin Galligan, Russell Wolf
KMMBridge Quick Start - CocoaPods
Getting Started With KMMBridge
Old KMMBridge Version
KMMBridge is at v1
This post was written for an earlier version of KMMBridge. Please see the new Quick Start.
The new version of KMMBridge and its tutorials focus on SPM, so there will be useful info here, but please use KMMBridge v1. The CocoaPods features are essentially unchanged.
Quick Start Continued
CocoaPods Setup
Publishing to CocoaPods requires a few extra steps. In summary, CocoaPods keeps it’s dependency info in a separate git repo. That means you will need to:
- Create (or have access to) a GitHub repo dedicated to storing CocoaPods version information.
- Configure CI with SSH key info to be able to push to that repo.
- Configure your clients to be able to access that repo (if not public).
Add a CocoaPods Podspec repo
CocoaPods keeps it’s config info, called “podspecs”, in a separate git repo. In our case, this means you’ll want to create a new empty repo on GitHub.
Create a repo in your org. We’ll call ours “Podspecs”. It can be public or private.
Important! Add at least one commit to this repo. The easiest option is to create a README. The CocoaPods process won’t push without an existing commit.
Next, you’ll need to enable access between these repos and our CI build workflow. Head over to the CocoaPods configuration section of the KMMBridge docs for details.
After you configure your keys, before you can publish, you’ll need to update the Framework config in allshared/build.gradle.kts
.
Update the Gradle Build
Our Kotlin Framework publication config in allshared/build.gradle.kts
needs a little work before we can use KMMBridge to publish with CocoaPods.
In a KMP project that builds Xcode Frameworks, you need to create the targets you want to build, and tell them to make Frameworks. You can do this explicitly, which is how the default template is configured:
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach {
it.binaries.framework {
export(project(":analytics"))
isStatic = true
}
}
To use that in an Xcode project, you need to connect it in some way. In the case of our test app, we use Direct Integration with embedAndSignAppleFrameworkForXcode
.
This config works for publishing to SPM.
For CocoaPods, we need more config info to construct the podspec and publish. We’ll need to add the Kotlin CocoaPods plugin and it’s associated configuration.
- Add the Kotlin CocoaPods Gradle plugin:
plugins {
kotlin("multiplatform")
id("co.touchlab.kmmbridge")
id("co.touchlab.skie")
kotlin("native.cocoapods") // <- Add this
`maven-publish`
}
- Replace the target and framework config with the following:
iosX64()
iosArm64()
iosSimulatorArm64()
cocoapods {
summary = "KMMBridgeSKIETemplate"
homepage = "https://www.touchlab.co"
ios.deploymentTarget = "13.5"
extraSpecAttributes["libraries"] = "'c++', 'sqlite3'"
license = "BSD"
extraSpecAttributes.put("swift_version", "\"5.0\"") // <- SKIE Needs this!
framework {
export(project(":analytics"))
isStatic = true
}
}
- Add the CocoaPods config to the
kmmbridge
block:
kmmbridge {
mavenPublishArtifacts()
spm()
cocoapods("git@github.com:[your org]/[your podspec repo].git")
}
build.gradle.kts
file can be found at part2/build.gradle.kts
More Info About the Kotlin CocoaPods Plugin
How the Kotlin CocoaPods plugin configures Frameworks
The Kotlin CocoaPods Gradle plugin is added with the following:
plugins {
kotlin("native.cocoapods")
}
This plugin is designed to enable local CocoaPods development. It does not support any kind of publication outside of your development machine. When discussing KMP integration with new teams, as SPM has increased in popularity, there is an automatic aversion to using CocoaPods for anything.
The local dev configuration has very little to do with how your projects are published.
I have to say that often, but it is a confusing situation.
Until very recently, local CocoaPods development was what I would recommend for everybody. While not perfect, the Kotlin CocoaPods plugin did a good job of automating builds. However, I’ve recently come to appreciate Direct Integration with embedAndSignAppleFrameworkForXcode
. In general we’ll be using that more often going forward.
To publish CocoaPods with KMMBridge, you need to use the Kotlin CocoaPods Gradle plugin, but only to get access to the config block. We’ll still use embedAndSignAppleFrameworkForXcode
for local test app development.
The part of Framework configuration that is sometimes confusing and the source of errors is that the Kotlin CocoaPods Gradle plugin automatically configures Apple/Darwin targets to build an Xcode Framework. It does this silently and automatically.
The reason our target config went from this:
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach {
it.binaries.framework {
export(project(":analytics"))
isStatic = true
}
}
to this:
iosX64()
iosArm64()
iosSimulatorArm64()
is because the Kotlin CocoaPods plugin automatically adds the framework { /* Etc */ }
config.
One common source of errors is actually the extra Framework config. People see tutorials with the explicit framework { /* Etc */ }
config and add that, then also add kotlin("native.cocoapods")
. Doing so will create duplicate Framework outputs for each target. For KMMBridge specifically, when you try to assemble the XCFramework, it will fail.
See KMMBridge - Troubleshooting for details.
Update GitHub Actions Workflows
Then, assuming you added the key secret in your Kotlin repo and called it PODSPEC_SSH_KEY
, open .github/workflows/All-publish.yml
and .github/workflows/KMMBridge-publish.yml
and uncomment the secret PODSPEC_SSH_KEY
param:
jobs:
call-kmmbridge-publish:
permissions:
contents: write
packages: write
uses: touchlab/KMMBridgeGithubWorkflow/.github/workflows/faktorybuildautoversion.yml@autoversion
with:
jvmVersion: 17
versionBaseProperty: LIBRARY_VERSION
publishTask: # etc
secrets:
PODSPEC_SSH_KEY: ${{ secrets.PODSPEC_SSH_KEY }}
Setting up the CocoaPods podspec has a lot of parts, so it is more likely that things will fail here. If you get issues, make sure to come back and double-check everything in this section.
Publish
Head over to your GitHub repo in your browser, find “Actions”, and run one of the build scripts. CocoaPods is very precise about deployment. There are multiple points that could fail, and if anything does, the overall deployment will fail. Once it is set up, you should rarely have issues, if ever, but debugging your initial setup can be tricky.
If you run into issued with deploy, reach out.
CocoaPods Client Setup
You’ll need to add the podsepc source repo, then include the project. Assuming your local GitHub access is configured, you should just need to edit your Podfile
.
See this doc for more detail.
platform :ios, '13.5'
source 'https://github.com/[your org]/KotlinPodspecs.git'
target '[Your iOS app target]' do
pod 'allshared', '~> 0.1'
end
Run pod install
, then open the .xcworkspace
file in Xcode.