UNPKG

expo-tiktok-business

Version:
282 lines 9.98 kB
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