Configuring the SDK
If this is your first time integrating RevenueCat into your app, we recommend following our Quickstart guide.
View our migration guide to v4.x here.
Basic Configuration
Initialization
Once you've installed the SDK for your app, it's time to initialize and configure it.
You should only configure Purchases once, usually early in your application lifecycle. After configuration, the same instance is shared throughout your app by accessing the .shared
instance in the SDK.
Make sure you configure Purchases with your public SDK key only. You can read more about the different API keys available in our Authentication guide.
- Swift
- SwiftUI
- Objective-C
- Kotlin
- Kotlin Multiplatform
- Java
- Flutter
- React Native
- Cordova
- Capacitor
- Unity
- Web (JS/TS)
import RevenueCat
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
Purchases.logLevel = .debug
Purchases.configure(withAPIKey: <public_apple_api_key>, appUserID: <app_user_id>)
}
import RevenueCat
@main
struct SampleApp: App {
init() {
Purchases.logLevel = .debug
Purchases.configure(withAPIKey: <public_apple_api_key>, appUserID: <app_user_id>)
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
RCPurchases.logLevel = RCLogLevelDebug;
[RCPurchases configureWithAPIKey:<public_apple_api_key> appUserID:<app_user_id>];
return YES;
}
// If you're targeting only Google Play Store
class MainApplication: Application() {
override fun onCreate() {
super.onCreate()
Purchases.debugLogsEnabled = true
Purchases.configure(PurchasesConfiguration.Builder(this, <public_google_api_key>).build())
}
}
// If you're building for the Amazon Appstore, you can use flavors to determine which keys to use
// In your build.gradle:
flavorDimensions "store"
productFlavors {
amazon {
buildConfigField "String", "STORE", "\"amazon\""
}
google {
buildConfigField "String", "STORE", "\"google\""
}
}
///...
class MainApplication: Application() {
override fun onCreate() {
super.onCreate()
Purchases.debugLogsEnabled = true
if (BuildConfig.STORE.equals("amazon")) {
Purchases.configure(AmazonConfiguration.Builder(this, <public_amazon_api_key>).build())
} else if (BuildConfig.STORE.equals("google")) {
Purchases.configure(PurchasesConfiguration.Builder(this, <public_google_api_key>).build())
}
}
}
// If you have common initialization logic, call configure() there. If not,
// call it early in the app's lifecycle on the respective platforms.
// Note: make sure you use the correct api key for each platform. You could
// use Kotlin Multiplatform's expect/actual mechanism for this.
Purchases.logLevel = LogLevel.DEBUG
Purchases.configure(apiKey = "<google_or_apple_api_key>") {
appUserId = "<app_user_id>"
// Other configuration options.
}
// If you're targeting only Google Play Store
public class MainApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Purchases.setDebugLogsEnabled(true);
Purchases.configure(new PurchasesConfiguration.Builder(this, <public_google_api_key>).build());
}
}
// If you're building for the Amazon Appstore,
// click the Kotlin tab to see how to set up flavors in your build.gradle:
///...
public class MainApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Purchases.setDebugLogsEnabled(true);
PurchasesConfiguration.Builder builder = null;
if (BuildConfig.STORE.equals("amazon")) {
builder = new AmazonConfiguration.Builder(this, "public_amazon_sdk_key");
} else if (BuildConfig.STORE.equals("google")) {
builder = new PurchasesConfiguration.Builder(this, "public_google_sdk_key");
}
Purchases.configure(builder.build());
}
}
import 'dart:io' show Platform;
//...
Future<void> initPlatformState() async {
await Purchases.setDebugLogsEnabled(true);
PurchasesConfiguration configuration;
if (Platform.isAndroid) {
configuration = PurchasesConfiguration(<public_google_api_key>);
if (buildingForAmazon) {
// use your preferred way to determine if this build is for Amazon store
// checkout our MagicWeather sample for a suggestion
configuration = AmazonConfiguration(<public_amazon_api_key>);
}
} else if (Platform.isIOS) {
configuration = PurchasesConfiguration(<public_apple_api_key>);
}
await Purchases.configure(configuration);
}
import { Platform } from 'react-native';
//...
export default class App extends React.Component {
componentDidMount() {
Purchases.setLogLevel(Purchases.LOG_LEVEL.DEBUG);
if (Platform.OS === 'ios') {
await Purchases.configure({ apiKey: <public_apple_api_key> });
} else if (Platform.OS === 'android') {
await Purchases.configure({ apiKey: <public_google_api_key> });
// OR: if building for Amazon, be sure to follow the installation instructions then:
await Purchases.configure({ apiKey: <public_amazon_api_key>, useAmazon: true });
}
}
}
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
Purchases.setDebugLogsEnabled(true);
if (window.cordova.platformId === 'ios') {
Purchases.configureWith({ apiKey: <public_apple_api_key> });
} else if (window.cordova.platformId === 'android') {
Purchases.configureWith({ apiKey: <public_google_api_key> });
}
// OR: if building for Amazon, be sure to follow the installation instructions then:
Purchases.configureWith({ apiKey: <public_amazon_api_key>, useAmazon: true });
}
const onDeviceReady = async () => {
await Purchases.setLogLevel({level: LOG_LEVEL.DEBUG});
if (Capacitor.getPlatform() === 'ios') {
await Purchases.configure({ apiKey: <public_apple_api_key> });
} else if (Capacitor.getPlatform() === 'android') {
await Purchases.configure({ apiKey: <public_google_api_key> });
}
// OR: if building for Amazon, be sure to follow the installation instructions then:
await Purchases.configure({ apiKey: <public_amazon_api_key>, useAmazon: true });
}
// The SDK can be configured through the Unity Editor.
// See Unity installation instructions https://docs.revenuecat.com/docs/unity
// If you'd like to configure the SDK programmatically,
// make sure to check "Use runtime setup" in the Unity Editor, and then:
Purchases.PurchasesConfiguration.Builder builder = Purchases.PurchasesConfiguration.Builder.Init(<public_api_key>);
Purchases.PurchasesConfiguration purchasesConfiguration =
.SetAppUserId(<app_user_id>)
.Build();
purchases.Configure(purchasesConfiguration);
const appUserId = authentication.getAppUserId(); // Replace with your own authentication system
const purchases = Purchases.configure(REVENUECAT_BILLING_PUBLIC_API_KEY, appUserId);
In certain cases, calling configure
in application:didFinishLaunchingWithOptions:
should be avoided. See Identifying Users for more information.
Using SwiftUI's App protocol? Check out our resource on setting up the Purchases SDK with SwiftUI.
Enabling Debug Logs
Be sure to enable and view debug logs before filing a ticket with RevenueCat Support.
As detailed in the sample code above, debug logs can be enabled or disabled by setting the Purchases.logLevel
property before configuring Purchases.
Debug logs will provide detailed log output in Xcode or LogCat for what is going on behind the scenes and should be the first thing you check if your app is behaving unexpectedly, and also to confirm there aren't any unhandled warnings or errors.
Additional Configuration Options
The SDK allows additional configuration on first setup:
- API Key (required): The public API key that corresponds to your app, found via Project Settings > API keys > App specific keys in the RevenueCat dashboard.
- App User ID (optional): An identifier for the current user. Pass
null
if you don't have a user identifier at the time of configuration and RevenueCat will generate an anonymous Id for you. See our guide on identifying users for more information. - Purchases Completed By (optional): A boolean value to tell RevenueCat not to complete purchases. Only set purchase completion to your app if you have your own code handling purchases.
- User Defaults (optional, iOS only): A key to override the standard user defaults used to cache
CustomerInfo
. This is required if you need to accessCustomerInfo
in an iOS App Extension.
Advanced Configuration
Additional configuration options on the .shared
instance of Purchases.
iOS
Delegates
DELEGATE
purchases:receivedUpdated
Called whenever Purchases receives an updated CustomerInfo
object. This may happen periodically throughout the life of the app if new information becomes available (e.g. after making a purchase).
Note: RevenueCat doesn't push new data to the SDK, so this method is only called when CustomerInfo is updated from another SDK method or after a purchase is made.
DELEGATE
purchases:readyForPromotedProduct
Called when a user initiates a promoted in-app purchase from the App Store. If your app is able to handle a purchase at the current time, run the defermentBlock
in this method. If the app is not in a state to make a purchase: cache the defermentBlock
, then call the defermentBlock
when the app is ready to make the promoted purchase. If the purchase should never be made, you don't need to ever call the defermentBlock
and Purchases will not proceed with promoted purchases.
Android
Listeners
LISTENER
UpdatedCustomerInfoListener
Called whenever Purchases receives an updated CustomerInfo
object. This may happen periodically throughout the life of the app if new information becomes available (e.g. after making a purchase).
Note: RevenueCat doesn't push new data to the SDK, so this method is only called when CustomerInfo is updated from another SDK method or after a purchase is made.
There is no way to import RevenueCat into NodeJS, we don't make any such modules or sdks. The best option is to use our APIs directly using Node fetch. In our API docs you should use our JavaScript language to do so.