When using Kotlin Multiplatform, the Kotlin/Native compiler produces a framework for iOS/macOS corresponding to the shared code
module (am assuming single module for purposes of this discussion). A number of different approaches are used then to ensure that the XCode project is wired
up to use that framework and that it is regenerated whenever an XCode build takes place after the shared code has been updated. These are typically based on use of CocoaPods plugin or custom gradle packForXCode()
type task that’s
executed from an XCode run script. What’s common in these approaches is that a say iOS developer needs to have access to the shared Kotlin code and
a setup to allow building the framework. Generally this is seen as being the preferred way of working (allowing all developers to
update and build the shared code as needed). However there are cases where it does make sense for the shared code to be consumed in XCode as a prebuilt
binary and one option for that is to publish/consume the code as a Swift Package. In this article I’m going to outline how this was done for
PeopleInSpace project using the Multiplatform Swift Package
Gradle plugin (note: see update at end of article:)
Update 21st Oct 2022: The really nice KMMBridge tool was recently released by Touchlab and would recommend using that now for generating/publishing Swift Packages as alternative to approach described in this article.
Swift Packages
Swift Packages are a relatively new concept that are described in official documentation as
…reusable components of Swift, Objective-C, Objective-C++, C, or C++ code that developers can use in their projects. They bundle source files, binaries, and resources in a way that’s easy to use in your app’s project.
The above mentioned plugin makes use of the ability provided to distribute binary frameworks
as Swift Packages (in particular, what are known as XCFrameworks
).
Project setup
To make use of the plugin we added following to build.gradle.kts
in the common
module
1
id("com.chromaticnoise.multiplatform-swiftpackage") version "2.0.3"
and then added following to set various configuration parameters needed (the plugin README has full list of options available)
1
2
3
4
5
6
7
multiplatformSwiftPackage {
packageName("PeopleInSpace")
swiftToolsVersion("5.3")
targetPlatforms {
iOS { v("13") }
}
}
With those updates we can now run ./gradlew createSwiftPackage
which will write generated files to common/swiftpackage
directory (this can
be customised if needed).
Publishing Swift Package to Github
GitHub Packages supports the publication/hosting of Swift Packages. For the purposes of this evaluation we created a separate PeopleInSpacePackage repository to which the artifacts generated by the plugin were pushed. An example of how to do that is shown here. Note also that git tags are used as mechanism to version the published package.
Consume Swift Package in XCode
This article outlines how to add Swift Package dependencies
to your XCode project. As we’ve published our package to Github you’ll need to setup associated account in XCode settings. Now when you select
“Swift Packages/Add Package Dependency…” from File menu you’ll see likes of following allowing you to select/add PeopleInSpacePackage
package.
We can now import the associated module in our Swift code and start making use of our Kotlin Multiplatform shared code!
Update Jan 24th 2020: Also created Swift Package for Bike Share
Note: if you’re having problems with package name to use in import in Swift code then you might be running in to this issue
Featured in Kotlin Weekly Issue #234 and Android Weekly Issue #450
Update September 17th 2022: The Multiplatform Swift Package library mentioned above is no longer being maintained and in particular is missing M1 support. However a fork has been created which adds this support and also is publishing artefacts that include those updates. More info here.
Related tweet
Using Swift Packages in a Kotlin Multiplatform project https://t.co/lRVgQxPf3b
— John O'Reilly (@joreilly) January 21, 2021
Wrote short article on exploring use of Swift Packages (published to Github) as way to distribute/consume #KotlinMultiplatform shared code as prebuilt binaries. Thanks @kpgalligan for looking over it. pic.twitter.com/KZFGrKAyxs