Kotlin Multiplatform
What is RevenueCat?โ
RevenueCat provides a backend and a wrapper around StoreKit and Google Play Billing to make implementing in-app purchases and subscriptions easy. With our SDK, you can build and manage your app business on any platform without having to maintain IAP infrastructure. You can read more about how RevenueCat fits into your app or you can sign up free to start building.
Requirementsโ
Android 5.0+ (API 21+)
iOS 13.0+
Installationโ
Adding the dependencyโ
Purchases for Kotlin Multiplatform (Google Play and iOS App Store) is available on Maven Central and can be included via Gradle.
Add the following coordinates to your libs.versions.toml
.
- libs.versions.toml
[versions]
purchases-kmp = "1.1.0+13.3.0"
[libraries]
# Required
purchases-core = { module = "com.revenuecat.purchases:purchases-kmp-core", version.ref = "purchases-kmp" }
# Optional: adds extension properties representing timestamps as kotlinx-datetime Instants.
purchases-datetime = { module = "com.revenuecat.purchases:purchases-kmp-datetime", version.ref = "purchases-kmp" }
# Optional: adds suspending functions that return Arrow's Either to indicate success / failure.
purchases-either = { module = "com.revenuecat.purchases:purchases-kmp-either", version.ref = "purchases-kmp" }
# Optional: adds suspending functions that return kotlin.Result to indicate success / failure.
purchases-result = { module = "com.revenuecat.purchases:purchases-kmp-result", version.ref = "purchases-kmp" }
You can now add the dependency to your commonMain
source set in your module's build.gradle.kts
.
- build.gradle.kts
kotlin {
// ...
sourceSets {
// ...
commonMain.dependencies {
// Add the purchases-kmp dependencies.
implementation(libs.purchases.core)
implementation(libs.purchases.datetime) // Optional
implementation(libs.purchases.either) // Optional
implementation(libs.purchases.result) // Optional
}
}
}
Opt in to ExperimentalForeignApiโ
Since the SDK uses generated Kotlin bindings for native code on iOS, you will need to opt in to ExperimentalForeignApi
in your iOS source sets. To do so, add the following to your module's build.gradle.kts
.
- build.gradle.kts
kotlin {
// ...
sourceSets {
// ...
named { it.lowercase().startsWith("ios") }.configureEach {
languageSettings {
optIn("kotlinx.cinterop.ExperimentalForeignApi")
}
}
}
}
Link the native iOS SDKโ
Since the SDK depends on a native RevenueCat iOS framework, PurchasesHybridCommon
, this will need to be linked to your existing iOS project. You have 2 options do to so: using Swift Package Manager and using CocoaPods. It's easiest to pick the dependency manager you're already using in your iOS project.
Using Swift Package Managerโ
To add PurchasesHybridCommon
to your iOS project using Swift Package Manager, do the following:
- Select
File ยป Add Packages Dependencies...
and enter the repository URLhttps://github.com/RevenueCat/purchases-hybrid-common
into the search bar (top right). - Then set the Dependency Rule to
Exact
, and specify the version number to be equal to everything after the '+' in the purchases-kmp version. - When "Choose Package Products for purchases-hybrid-common" appears, select
PurchasesHybridCommon
. If you plan to use Paywalls, selectPurchasesHybridCommonUI
too. - Lastly, click "Add Package".
The library should now have been added to the Package Dependencies section.
Using CocoaPodsโ
There are 2 approaches to add PurchasesHybridCommon
to your iOS project using CocoaPods. The approach depends on how you currently integrate your existing Kotlin Multiplatform code with your iOS project.
1. Directly as a local iOS frameworkโ
Follow these instructions if your Kotlin Multiplatform module is integrated directly with your iOS project as a local iOS framework. That is, Xcode is calling the embedAndSignAppleFrameworkForXcode
Gradle task (or the old packForXcode
task) as part of the build. At the time of writing, if you generated your Kotlin Multiplatform project using the online wizard, this is how it's set up.
In this scenario, you need to specify the transitive dependency on PurchasesHybridCommon
in your Podfile
. Add the following:
- Podfile
# This version must be equal to everything after the '+' in the purchases-kmp version.
pod 'PurchasesHybridCommon', '13.3.0'
2. Using Cocoapodsโ
Follow these instructions if your Kotlin Multiplatform module is integrated with your iOS project using CocoaPods. That is, you've applied the kotlin("native.cocoapods")
Gradle plugin, and set it up such that the Podfile
specifies a dependency on your Kotlin Multiplatform module. (See also the Kotlin docs.)
In this scenario, you can specify the transitive dependency on PurchasesHybridCommon
using Gradle. To do so, add the following to your libs.versions.toml
:
- libs.versions.toml
[versions]
# This version must be equal to everything after the '+' in the purchases-kmp version.
purchases-common = "13.3.0"
Now you can add the following to your module's build.gradle.kts
:
- build.gradle.kts
kotlin {
// ...
cocoapods {
// Your existing Cocoapods options are here.
// Add the PurchasesHybridCommon dependency.
pod("PurchasesHybridCommon") {
version = libs.versions.purchases.common.get()
extraOpts += listOf("-compiler-option", "-fmodules")
}
}
}
Set the correct launchMode for Androidโ
Depending on your user's payment method, they may be asked by Google Play to verify their purchase in their (banking) app. This means they will have to background your app and go to another app to verify the purchase. If your Activity's launchMode
is set to anything other than standard
or singleTop
, backgrounding your app can cause the purchase to get cancelled. To avoid this, set the launchMode
of your Activity to standard
or singleTop
in your Android app's AndroidManifest.xml
file:
- AndroidManifest.xml
<activity
android:name="com.your.Activity"
android:launchMode="standard" /> <!-- or singleTop -->
You can find Android's documentation on the various launchMode
options here.
Import Purchasesโ
You should now be able to import Purchases
.
- commonMain
import com.revenuecat.purchases.kmp.CustomerInfo
import com.revenuecat.purchases.kmp.Entitlement
import com.revenuecat.purchases.kmp.Offering
import com.revenuecat.purchases.kmp.Purchases
import com.revenuecat.purchases.kmp.models.Period
import com.revenuecat.purchases.kmp.models.Price
import com.revenuecat.purchases.kmp.models.StoreProduct
On Android, Purchases uses AndroidX App Startup under the hood. Make sure you have not removed the androidx.startup.InitializationProvider
completely in your manifest. If you need to remove specific initializers, such as androidx.work.WorkManagerInitializer
, set tools:node="merge"
on the provider, and tools:node="remove"
on the meta-data of the initializer you want to remove.
- AndroidManifest.xml
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data
android:name="androidx.work.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>
Next Stepsโ
- Now that you've installed the Purchases SDK in Kotlin Multiplatform, get started by configuring an instance of Purchases โ