To ensure that your application is not blocked in China and works efficiently, Adapty provides a China cluster option. This ensures fast and reliable service for your users in mainland China while helping you comply with local regulations.
The Great Firewall of China can significantly impact connectivity and performance for applications using servers hosted outside the country.
However, Adapty’s China-based infrastructure allows your application to deliver consistent, reliable performance to users in mainland China.
In China, applications require explicit user permission to access the internet. Until this permission is granted, no network requests will work. Ensure your application:
- Requests internet access permission appropriately.
- Handles cases where permission is denied or not yet granted.
- Provides clear user guidance about why internet access is needed.
Install Adapty SDK as described in the installation guide .
For the China region, when configuring the SDK during the installation, follow the instructions depending on your framework:
During configuration, add the China cluster as follows:
Set the cluster as .with(serverCluster: .cn) in your configuration.
// In your AppDelegate class:
import Adapty
let configurationBuilder =
AdaptyConfiguration
.Builder(withAPIKey: "PUBLIC_SDK_KEY")
.with(observerMode: false)
.with(customerUserId: "YOUR_USER_ID")
.with(serverCluster: .cn)
Adapty.activate(with: configurationBuilder.build()) { error in
// handle the error
}
import Adapty
@main
struct SampleApp: App {
init()
let configurationBuilder =
AdaptyConfiguration
.Builder(withAPIKey: "PUBLIC_SDK_KEY")
.with(observerMode: false) // optional
.with(customerUserId: "YOUR_USER_ID") // optional
.with(serverCluster: .cn)
Adapty.activate(with: configurationBuilder.build()) { error in
// handle the error
}
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
Parameters:
| Parameter | Description |
|---|
| serverCluster | Use the .cn value to connect your app to Adapty’s China servers. |
During configuration, add the China cluster as follows:
Use the .withServerCluster method in your configuration:
override fun onCreate() {
super.onCreate()
Adapty.activate(
applicationContext,
AdaptyConfig.Builder("PUBLIC_SDK_KEY")
.withObserverMode(false) //default false
.withCustomerUserId(customerUserId) //default null
.withServerCluster(AdaptyConfig.ServerCluster.CN)
.build()
)
}
@Override
public void onCreate() {
super.onCreate();
Adapty.activate(
applicationContext,
new AdaptyConfig.Builder("PUBLIC_SDK_KEY")
.withObserverMode(false) //default false
.withCustomerUserId(customerUserId) //default null
.withServerCluster(AdaptyConfig.ServerCluster.CN)
.build()
);
}
Added method:
| Method | Description |
|---|
| withServerCluster | Pass the value AdaptyConfig.ServerCluster.CN to it to connect your app to Adapty’s China servers. |
For React Native applications, configure the China cluster as follows:
import Adapty from 'react-native-adapty';
// Initialize Adapty with China servers
await Adapty.activate({
sdkKey: 'PUBLIC_SDK_KEY',
observerMode: false, // optional, default false
customerUserId: 'YOUR_USER_ID', // optional
serverCluster: 'cn', // Use 'cn' for China servers
});
Parameters:
| Parameter | Description |
|---|
| serverCluster | Use the value 'cn' to connect to China servers. |
For Flutter applications, configure the China cluster as follows:
import 'package:adapty_flutter/adapty_flutter.dart';
await Adapty().activate(
configuration: AdaptyConfiguration(apiKey: 'PUBLIC_SDK_KEY')
..withServerCluster(AdaptyServerCluster.cn)
..withCustomerUserId('YOUR_USER_ID'),
);
Parameters:
| Parameter | Description |
|---|
| serverCluster | Use the value AdaptyServerCluster.cn for China servers. |
The China cluster requires Adapty Kotlin Multiplatform SDK 4.0 (beta) or later.
Use the .withServerCluster method in your configuration:
import com.adapty.kmp.Adapty
import com.adapty.kmp.models.AdaptyConfig
val config = AdaptyConfig
.Builder("PUBLIC_SDK_KEY")
.withObserverMode(false) // default false
.withCustomerUserId(customerUserId) // default null
.withServerCluster(AdaptyConfig.ServerCluster.CN)
.build()
Adapty.activate(configuration = config)
.onError { error ->
// handle the error
}
Added method:
| Method | Description |
|---|
| withServerCluster | Pass the value AdaptyConfig.ServerCluster.CN to it to connect your app to Adapty’s China servers. |
After configuring the China server cluster, you can use the Adapty Dashboard as usual at app.adapty.io. The dashboard experience is identical regardless of which server cluster you’re using.
Step 2. Detect when to use China servers
It’s important to dynamically choose between global and China-specific servers based on user location. Here are two approaches:
Option 1: Detect by region/country
func shouldUseChinaServers() -> Bool {
Locale.current.regionCode == "CN"
}
// In your configuration
let configurationBuilder = AdaptyConfiguration
.Builder(withAPIKey: "PUBLIC_SDK_KEY")
if shouldUseChinaServers() {
configurationBuilder.with(serverCluster: .cn)
}
// other configuration options
import { NativeModules, Platform } from 'react-native';
import Adapty from 'react-native-adapty';
import { getCountry } from 'react-native-localize';
async function initializeAdapty() {
// Determine if user is in China
const shouldUseChinaServers = () => getCountry() === "CN";
// Initialize with appropriate server
await Adapty.activate({
sdkKey: 'PUBLIC_SDK_KEY',
serverCluster: shouldUseChinaServers ? 'cn' : 'default',
// other configuration options
});
}
// Call the initialization function
initializeAdapty();
// Define the helper function
private fun shouldUseChinaServers() = Locale.getDefault().country == "CN"
// Use it in configuration
private fun setupAdapty() {
val serverCluster = if (shouldUseChinaServers())
AdaptyConfig.ServerCluster.CN
else
AdaptyConfig.ServerCluster.DEFAULT
Adapty.activate(
context,
AdaptyConfig.Builder("PUBLIC_SDK_KEY")
// other configuration options
.withServerCluster(serverCluster)
.build()
)
}
Option 2: Detect by app store
For applications distributed through different app stores, you can determine which server to use based on the installation source:
import StoreKit
func shouldUseChinaServers() async -> Bool {
let code: String?
if #available(iOS 15.0, *) {
code = await Storefront.current?.countryCode
} else {
code = SKPaymentQueue.default().storefront?.countryCode
}
return code == "CHN"
}
// In your configuration
let configurationBuilder = AdaptyConfiguration
.Builder(withAPIKey: "PUBLIC_SDK_KEY")
// Only set server cluster if it's China
if await shouldUseChinaServers() {
configurationBuilder.with(serverCluster: .cn)
}
// other configuration options
import { Platform } from 'react-native';
import Adapty from 'react-native-adapty';
import { isChineseStore } from './storeDetection'; // Implement this based on your store detection logic
async function initializeAdapty() {
// For Android, determine if the app was installed from a Chinese app store
// For iOS, you might check the storefront country
const shouldUseChinaServers = Platform.OS === 'android'
? await isChineseStore()
: await isChineseStorefront();
// Initialize with appropriate server
await Adapty.activate({
sdkKey: 'PUBLIC_SDK_KEY',
serverCluster: shouldUseChinaServers ? 'cn' : 'default',
// other configuration options
});
}
// Example implementation for Android (simplified)
async function isChineseStore() {
try {
// Check if the app was installed from a Chinese app store
// This is a simplified example - implement proper store detection based on your distribution channels
const { installerPackageName } = await NativeModules.InstallerInfo.getInstallerInfo();
const chineseStores = [
'com.huawei.appmarket', // Huawei AppGallery
'com.xiaomi.market', // Xiaomi GetApps
'com.oppo.market', // OPPO App Market
'com.vivo.appstore', // Vivo App Store
// Add other Chinese app stores as needed
];
return chineseStores.includes(installerPackageName);
} catch (error) {
console.error('Error detecting store:', error);
return false;
}
}
// Example implementation for iOS (simplified)
async function isChineseStorefront() {
// Implementation depends on how you detect the App Store region
// This would typically involve checking receipt information or other store data
// Simplified example:
return await NativeModules.StoreHelper.isChineseStorefront();
}
// Call the initialization function
initializeAdapty();