expo-tiktok-business
Version:
A expo module for tiktok business sdk
282 lines • 9.98 kB
JavaScript
import { requireNativeModule } from 'expo-modules-core';
import { AppState, Platform } from "react-native";
import Constants from "expo-constants";
import { TiktokEventName } from "./TiktokSDK.types";
// Create a getter function for the native module that will be called when needed
const getNativeModule = () => {
try {
// Use the modern requireNativeModule approach instead of deprecated NativeModulesProxy
console.log('Attempting to load TiktokSDK native module...');
const module = requireNativeModule('TiktokSDK');
console.log('TiktokSDK native module loaded:', module ? 'SUCCESS' : 'FAILED');
console.log('Platform:', Platform.OS);
return module || null;
}
catch (error) {
console.error('Error accessing TiktokSDK native module:', error);
return null;
}
};
/**
* TikTok Business SDK wrapper class
*/
class TiktokSDK {
_isInitialized = false;
_config;
_appStateSubscription = null;
/**
* Get the bundle ID or package name for the current platform
* @private
*/
_getPlatformAppId(appId) {
if (typeof appId === 'string') {
return appId;
}
const platform = Platform.OS;
if (platform === 'ios' && appId.ios) {
return appId.ios;
}
else if (platform === 'android' && appId.android) {
return appId.android;
}
return appId.default;
}
/**
* Get the TikTok App ID for the current platform
* @private
*/
_getPlatformTikTokAppId(tiktokAppId) {
if (typeof tiktokAppId === 'string') {
return tiktokAppId;
}
const platform = Platform.OS;
if (platform === 'ios' && tiktokAppId.ios) {
return tiktokAppId.ios;
}
else if (platform === 'android' && tiktokAppId.android) {
return tiktokAppId.android;
}
return tiktokAppId.default;
}
/**
* Try to get the app's bundle ID/package name from Expo Constants
* @private
*/
_tryGetExpoBundleId() {
try {
// Try to get the bundle ID from Expo Constants
const { manifest } = Constants;
if (manifest) {
// For Expo SDK 46 and above
if (manifest.extra && manifest.extra.expoClient) {
if (Platform.OS === 'ios' && manifest.extra.expoClient.ios && manifest.extra.expoClient.ios.bundleIdentifier) {
return manifest.extra.expoClient.ios.bundleIdentifier;
}
else if (Platform.OS === 'android' && manifest.extra.expoClient.android && manifest.extra.expoClient.android.package) {
return manifest.extra.expoClient.android.package;
}
}
// For older Expo SDK versions
if (Platform.OS === 'ios' && manifest.ios && manifest.ios.bundleIdentifier) {
return manifest.ios.bundleIdentifier;
}
else if (Platform.OS === 'android' && manifest.android && manifest.android.package) {
return manifest.android.package;
}
}
}
catch (error) {
console.warn('TiktokSDK: Failed to get bundle ID from Expo Constants', error);
}
return null;
}
/**
* Initialize the TikTok Business SDK
* @param appIdParam Your app ID or platform-specific app IDs
* @param tiktokAppIdParam Your TikTok app ID or platform-specific TikTok app IDs
* @param options Additional configuration options
*/
async initialize(appIdParam, tiktokAppIdParam, options = {}) {
// Get platform-specific app ID
let appId;
if (typeof appIdParam === 'string') {
appId = appIdParam;
}
else {
appId = this._getPlatformAppId(appIdParam);
}
// Get platform-specific TikTok app ID
let tiktokAppId;
if (typeof tiktokAppIdParam === 'string') {
tiktokAppId = tiktokAppIdParam;
}
else {
tiktokAppId = this._getPlatformTikTokAppId(tiktokAppIdParam);
}
// Create config
const config = {
appId,
tiktokAppId,
debugMode: options.debugMode || false,
autoTrackAppLifecycle: options.autoTrackAppLifecycle !== false, // default to true
autoTrackRouteChanges: options.autoTrackRouteChanges !== false, // default to true,
};
this._config = config;
if (config.debugMode) {
console.log(`TiktokSDK: Initializing for ${Platform.OS} with appId=${appId}, tiktokAppId=${tiktokAppId}`);
}
// Initialize the native SDK
const module = getNativeModule();
if (!module) {
console.error("TiktokSDK: Native module not available");
return false;
}
try {
const success = await module.initialize(config) || false;
this._isInitialized = success;
// Set up app state change listener if lifecycle tracking is enabled
if (success && config.autoTrackAppLifecycle) {
this._setupAppStateListener();
}
return success;
}
catch (error) {
console.error("TiktokSDK: Error initializing SDK", error);
return false;
}
}
/**
* Set debug mode for the SDK
* @param enabled Whether to enable debug mode
*/
async setDebugMode(enabled) {
const module = getNativeModule();
if (!module) {
console.error("TiktokSDK: Native module not available");
return false;
}
try {
return await module.setDebugMode(enabled) || false;
}
catch (error) {
console.error("TiktokSDK: Error setting debug mode", error);
return false;
}
}
/**
* Track a standard or custom event
* @param eventName Event name (use TiktokEventName for standard events)
* @param eventParams Event parameters
*/
async trackEvent(eventName, eventParams = {}) {
if (!this._isInitialized) {
console.warn("TiktokSDK: SDK not initialized. Call initialize() first.");
return false;
}
const module = getNativeModule();
if (!module) {
console.error("TiktokSDK: Native module not available");
return false;
}
try {
return await module.trackEvent(eventName, eventParams) || false;
}
catch (error) {
console.error("TiktokSDK: Error tracking event", error);
return false;
}
}
/**
* Track a route change (screen view) - useful for manual tracking
* @param routeName The name of the route/screen
* @param params Optional route parameters
*/
async trackRouteChange(routeName, params) {
if (!this._isInitialized) {
return false;
}
const module = getNativeModule();
if (!module) {
console.error("TiktokSDK: Native module not available");
return false;
}
try {
return await module.trackRouteChange(routeName, params) || false;
}
catch (error) {
console.error("TiktokSDK: Error tracking route change", error);
return false;
}
}
/**
* Helper: Track a search event
* @param searchString The search query
* @param additionalParams Additional event parameters
*/
async trackSearch(searchString, additionalParams = {}) {
return this.trackEvent(TiktokEventName.SEARCH, {
search_string: searchString,
...additionalParams,
});
}
/**
* Helper: Track a content view
* @param contentId Content ID
* @param contentType Content type
* @param additionalParams Additional event parameters
*/
async trackViewContent(contentId, contentType, additionalParams = {}) {
return this.trackEvent(TiktokEventName.VIEW_CONTENT, {
content_id: contentId,
content_type: contentType,
...additionalParams,
});
}
/**
* Helper: Track a completed purchase
* @param value The monetary value of the purchase
* @param currency The currency code (e.g., USD)
* @param contents The purchased items
* @param additionalParams Additional event parameters
*/
async trackCompletePurchase(value, currency, contents, additionalParams = {}) {
return this.trackEvent(TiktokEventName.COMPLETE_PAYMENT, {
value,
currency,
contents,
...additionalParams,
});
}
/**
* Clean up resources when the module is no longer needed
*/
cleanup() {
if (this._appStateSubscription) {
this._appStateSubscription.remove();
this._appStateSubscription = null;
}
}
/**
* Set up app state listener for automatic event tracking
*/
_setupAppStateListener() {
// Clean up existing listener if any
if (this._appStateSubscription) {
this._appStateSubscription.remove();
}
// Set up new listener
this._appStateSubscription = AppState.addEventListener('change', this._handleAppStateChange);
}
/**
* Handle app state changes for automatic event tracking
*/
_handleAppStateChange = (nextAppState) => {
if (nextAppState === 'active') {
// App came to foreground - could track a custom event here if needed
// We don't track Launch here as it's handled during initialization
}
};
}
// Export the singleton instance
export default new TiktokSDK();
//# sourceMappingURL=TiktokSDKModule.js.map