expo-facebook-analytics 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +242 -0
  2. package/android/build.gradle +60 -0
  3. package/android/src/main/java/com/nitrofbanalytics/HybridFacebookAnalytics.kt +139 -0
  4. package/app.plugin.js +1 -0
  5. package/expo-facebook-analytics.podspec +31 -0
  6. package/ios/HybridFacebookAnalytics.swift +135 -0
  7. package/lib/index.d.ts +58 -0
  8. package/lib/index.js +138 -0
  9. package/lib/specs/FacebookAnalytics.nitro.d.ts +20 -0
  10. package/lib/specs/FacebookAnalytics.nitro.js +2 -0
  11. package/lib/types.d.ts +65 -0
  12. package/lib/types.js +52 -0
  13. package/nitro.json +19 -0
  14. package/nitrogen/generated/.gitattributes +1 -0
  15. package/nitrogen/generated/android/NitroFBAnalytics+autolinking.cmake +81 -0
  16. package/nitrogen/generated/android/NitroFBAnalytics+autolinking.gradle +27 -0
  17. package/nitrogen/generated/android/NitroFBAnalyticsOnLoad.cpp +44 -0
  18. package/nitrogen/generated/android/NitroFBAnalyticsOnLoad.hpp +25 -0
  19. package/nitrogen/generated/android/c++/JHybridFacebookAnalyticsSpec.cpp +157 -0
  20. package/nitrogen/generated/android/c++/JHybridFacebookAnalyticsSpec.hpp +79 -0
  21. package/nitrogen/generated/android/kotlin/com/margelo/nitro/com/nitrofbanalytics/HybridFacebookAnalyticsSpec.kt +110 -0
  22. package/nitrogen/generated/android/kotlin/com/margelo/nitro/com/nitrofbanalytics/NitroFBAnalyticsOnLoad.kt +35 -0
  23. package/nitrogen/generated/ios/NitroFBAnalytics+autolinking.rb +60 -0
  24. package/nitrogen/generated/ios/NitroFBAnalytics-Swift-Cxx-Bridge.cpp +49 -0
  25. package/nitrogen/generated/ios/NitroFBAnalytics-Swift-Cxx-Bridge.hpp +171 -0
  26. package/nitrogen/generated/ios/NitroFBAnalytics-Swift-Cxx-Umbrella.hpp +47 -0
  27. package/nitrogen/generated/ios/NitroFBAnalyticsAutolinking.mm +33 -0
  28. package/nitrogen/generated/ios/NitroFBAnalyticsAutolinking.swift +26 -0
  29. package/nitrogen/generated/ios/c++/HybridFacebookAnalyticsSpecSwift.cpp +11 -0
  30. package/nitrogen/generated/ios/c++/HybridFacebookAnalyticsSpecSwift.hpp +167 -0
  31. package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +47 -0
  32. package/nitrogen/generated/ios/swift/Func_void_std__optional_std__string_.swift +54 -0
  33. package/nitrogen/generated/ios/swift/HybridFacebookAnalyticsSpec.swift +69 -0
  34. package/nitrogen/generated/ios/swift/HybridFacebookAnalyticsSpec_cxx.swift +410 -0
  35. package/nitrogen/generated/shared/c++/HybridFacebookAnalyticsSpec.cpp +34 -0
  36. package/nitrogen/generated/shared/c++/HybridFacebookAnalyticsSpec.hpp +78 -0
  37. package/package.json +66 -0
  38. package/plugin/build/index.d.ts +13 -0
  39. package/plugin/build/index.js +42 -0
  40. package/plugin/build/withFacebookAnalyticsAndroid.d.ts +14 -0
  41. package/plugin/build/withFacebookAnalyticsAndroid.js +67 -0
  42. package/plugin/build/withFacebookAnalyticsIOS.d.ts +16 -0
  43. package/plugin/build/withFacebookAnalyticsIOS.js +96 -0
  44. package/src/index.ts +161 -0
  45. package/src/specs/FacebookAnalytics.nitro.ts +47 -0
  46. package/src/types.ts +67 -0
package/README.md ADDED
@@ -0,0 +1,242 @@
1
+ # expo-facebook-analytics
2
+
3
+ High-performance Facebook Analytics for React Native using [Nitro Modules](https://github.com/mrousavy/nitro).
4
+
5
+ ## Features
6
+
7
+ - Direct native Facebook SDK integration via Nitro Modules (zero-copy bridge)
8
+ - Full event logging, user identity management, and device identifier access
9
+ - Expo config plugin for automatic native setup
10
+ - TypeScript-first with predefined event and parameter constants
11
+ - iOS 13+ and Android SDK 21+
12
+
13
+ ## Installation
14
+
15
+ ```sh
16
+ bun add expo-facebook-analytics react-native-nitro-modules
17
+ ```
18
+
19
+ or
20
+
21
+ ```sh
22
+ npm install expo-facebook-analytics react-native-nitro-modules
23
+ ```
24
+
25
+ ### Peer Dependencies
26
+
27
+ - `react-native` >= 0.71
28
+ - `react-native-nitro-modules` >= 0.33.2
29
+ - `expo` >= 55.0.4 _(optional, for config plugin)_
30
+
31
+ ### iOS
32
+
33
+ ```sh
34
+ cd ios && pod install
35
+ ```
36
+
37
+ ### Android
38
+
39
+ No additional steps required — Gradle handles the Facebook SDK dependency automatically.
40
+
41
+ ## Expo Setup
42
+
43
+ Add the plugin to your `app.json` / `app.config.js`:
44
+
45
+ ```json
46
+ {
47
+ "expo": {
48
+ "plugins": [
49
+ [
50
+ "expo-facebook-analytics",
51
+ {
52
+ "appID": "YOUR_FACEBOOK_APP_ID",
53
+ "clientToken": "YOUR_FACEBOOK_CLIENT_TOKEN",
54
+ "displayName": "Your App Name"
55
+ }
56
+ ]
57
+ ]
58
+ }
59
+ }
60
+ ```
61
+
62
+ ### Plugin Options
63
+
64
+ | Option | Type | Default | Description |
65
+ | ------------------------------- | --------------------- | ------------- | ------------------------------------------ |
66
+ | `appID` | `string` | **required** | Facebook App ID |
67
+ | `clientToken` | `string` | **required** | Facebook Client Token |
68
+ | `displayName` | `string` | App name | Display name for Facebook |
69
+ | `scheme` | `string` | `fb{appID}` | URL scheme for deep linking |
70
+ | `isAutoInitEnabled` | `boolean` | `true` | Auto-initialize Facebook SDK |
71
+ | `autoLogAppEventsEnabled` | `boolean` | `true` | Automatically log app events |
72
+ | `advertiserIDCollectionEnabled` | `boolean` | `true` | Enable advertiser ID collection |
73
+ | `iosUserTrackingPermission` | `string` \| `false` | ATT prompt | Custom tracking permission text or disable |
74
+
75
+ ### Manual Native Setup
76
+
77
+ If you're not using Expo, refer to the [Facebook SDK documentation](https://developers.facebook.com/docs/app-events/getting-started-app-events-android/) for manual iOS and Android configuration.
78
+
79
+ ## Usage
80
+
81
+ ### Log Events
82
+
83
+ ```typescript
84
+ import { logEvent, logPurchase, AppEvents, AppEventParams } from 'expo-facebook-analytics';
85
+
86
+ // Simple event
87
+ logEvent(AppEvents.ViewedContent);
88
+
89
+ // Event with a numeric value
90
+ logEvent(AppEvents.Searched, 1);
91
+
92
+ // Event with parameters
93
+ logEvent(AppEvents.AddedToCart, {
94
+ [AppEventParams.ContentID]: 'product-123',
95
+ [AppEventParams.ContentType]: 'product',
96
+ [AppEventParams.Currency]: 'USD',
97
+ });
98
+
99
+ // Event with value and parameters
100
+ logEvent(AppEvents.Purchased, 29.99, {
101
+ [AppEventParams.Currency]: 'USD',
102
+ [AppEventParams.NumItems]: 2,
103
+ });
104
+
105
+ // Log a purchase
106
+ logPurchase(29.99, 'USD', {
107
+ [AppEventParams.ContentID]: 'product-123',
108
+ });
109
+
110
+ // Log push notification open
111
+ logPushNotificationOpen({ campaign: 'summer-sale' });
112
+ ```
113
+
114
+ ### User Identity
115
+
116
+ ```typescript
117
+ import { setUserID, getUserID, clearUserID, setUserData } from 'expo-facebook-analytics';
118
+
119
+ // Set user ID for analytics
120
+ setUserID('user-123');
121
+
122
+ // Get current user ID
123
+ const userId = getUserID();
124
+
125
+ // Clear user ID
126
+ clearUserID();
127
+
128
+ // Set user data for advanced matching
129
+ setUserData({
130
+ email: 'user@example.com',
131
+ firstName: 'John',
132
+ lastName: 'Doe',
133
+ gender: 'm',
134
+ city: 'San Francisco',
135
+ state: 'CA',
136
+ country: 'US',
137
+ });
138
+ ```
139
+
140
+ ### Device Identifiers
141
+
142
+ ```typescript
143
+ import { getAnonymousID, getAdvertiserID } from 'expo-facebook-analytics';
144
+
145
+ const anonId = await getAnonymousID();
146
+ const advertiserId = await getAdvertiserID(); // IDFA on iOS, AAID on Android
147
+ ```
148
+
149
+ ### Configuration
150
+
151
+ ```typescript
152
+ import { setFlushBehavior, flush, setPushNotificationsDeviceToken, setPushNotificationsRegistrationId } from 'expo-facebook-analytics';
153
+
154
+ // Control event batching: 'auto' (default) or 'explicit_only'
155
+ setFlushBehavior('explicit_only');
156
+
157
+ // Manually flush queued events
158
+ flush();
159
+
160
+ // Push notification tokens
161
+ setPushNotificationsDeviceToken(apnsToken); // iOS
162
+ setPushNotificationsRegistrationId(fcmToken); // Android
163
+ ```
164
+
165
+ ## API Reference
166
+
167
+ ### Event Logging
168
+
169
+ | Function | Description |
170
+ | --------------------------- | ------------------------------------ |
171
+ | `logEvent(name, ...args)` | Log a custom or predefined event |
172
+ | `logPurchase(amount, currency, params?)` | Log a purchase event |
173
+ | `logPushNotificationOpen(payload?)` | Log a push notification open |
174
+
175
+ ### User Identity
176
+
177
+ | Function | Description |
178
+ | ----------------------- | ---------------------------------- |
179
+ | `setUserID(id)` | Set the user ID for analytics |
180
+ | `clearUserID()` | Clear the current user ID |
181
+ | `getUserID()` | Get the current user ID |
182
+ | `setUserData(data)` | Set user data for advanced matching|
183
+
184
+ ### Device Identifiers
185
+
186
+ | Function | Description |
187
+ | --------------------- | ------------------------------------------- |
188
+ | `getAnonymousID()` | Get the anonymous device ID |
189
+ | `getAdvertiserID()` | Get IDFA (iOS) or AAID (Android) |
190
+
191
+ ### Configuration
192
+
193
+ | Function | Description |
194
+ | ------------------------------------- | ---------------------------------- |
195
+ | `setFlushBehavior(behavior)` | Set event flush behavior |
196
+ | `flush()` | Flush queued events immediately |
197
+ | `setPushNotificationsDeviceToken(t)` | Set APNs push token (iOS) |
198
+ | `setPushNotificationsRegistrationId(id)` | Set FCM registration ID (Android) |
199
+
200
+ ## Predefined Constants
201
+
202
+ ### AppEvents
203
+
204
+ `AchievedLevel`, `AdClick`, `AdImpression`, `AddedPaymentInfo`, `AddedToCart`, `AddedToWishlist`, `CompletedRegistration`, `CompletedTutorial`, `Contact`, `CustomizeProduct`, `Donate`, `FindLocation`, `InitiatedCheckout`, `Purchased`, `Rated`, `Schedule`, `Searched`, `SpentCredits`, `StartTrial`, `SubmitApplication`, `Subscribe`, `UnlockedAchievement`, `ViewedContent`
205
+
206
+ ### AppEventParams
207
+
208
+ `AddType`, `Content`, `ContentID`, `ContentType`, `Currency`, `Description`, `Level`, `MaxRatingValue`, `NumItems`, `OrderId`, `PaymentInfoAvailable`, `RegistrationMethod`, `SearchString`, `Success`, `ValueNo`, `ValueYes`
209
+
210
+ ## Types
211
+
212
+ ```typescript
213
+ type Params = { [key: string]: string | number };
214
+
215
+ type UserData = Readonly<{
216
+ email?: string;
217
+ firstName?: string;
218
+ lastName?: string;
219
+ phone?: string;
220
+ dateOfBirth?: string;
221
+ gender?: 'm' | 'f';
222
+ city?: string;
223
+ state?: string;
224
+ zip?: string;
225
+ country?: string;
226
+ }>;
227
+
228
+ type AppEventsFlushBehavior = 'auto' | 'explicit_only';
229
+ ```
230
+
231
+ ## Requirements
232
+
233
+ | Platform | Minimum Version |
234
+ | -------- | --------------- |
235
+ | iOS | 13.0 |
236
+ | Android | SDK 21 |
237
+
238
+ Native SDKs: Facebook SDK ~17.0
239
+
240
+ ## License
241
+
242
+ MIT
@@ -0,0 +1,60 @@
1
+ buildscript {
2
+ ext.safeExtGet = {prop, fallback ->
3
+ rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
4
+ }
5
+ repositories {
6
+ google()
7
+ mavenCentral()
8
+ }
9
+ dependencies {
10
+ classpath("com.android.tools.build:gradle:8.2.0")
11
+ classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22")
12
+ }
13
+ }
14
+
15
+ apply plugin: 'com.android.library'
16
+ apply plugin: 'kotlin-android'
17
+
18
+ def nitrogenAutolinking = file("nitrogen/generated/android/NitroFBAnalytics-autolinking.gradle")
19
+ if (nitrogenAutolinking.exists()) {
20
+ apply from: nitrogenAutolinking
21
+ }
22
+
23
+ android {
24
+ namespace 'com.nitrofbanalytics'
25
+ compileSdkVersion safeExtGet('compileSdkVersion', 34)
26
+
27
+ defaultConfig {
28
+ minSdkVersion safeExtGet('minSdkVersion', 21)
29
+ targetSdkVersion safeExtGet('targetSdkVersion', 34)
30
+ }
31
+
32
+ sourceSets {
33
+ main {
34
+ java.srcDirs += [
35
+ 'src/main/java',
36
+ 'nitrogen/generated/android/kotlin'
37
+ ]
38
+ }
39
+ }
40
+
41
+ compileOptions {
42
+ sourceCompatibility JavaVersion.VERSION_1_8
43
+ targetCompatibility JavaVersion.VERSION_1_8
44
+ }
45
+
46
+ kotlinOptions {
47
+ jvmTarget = '1.8'
48
+ }
49
+ }
50
+
51
+ repositories {
52
+ google()
53
+ mavenCentral()
54
+ }
55
+
56
+ dependencies {
57
+ implementation 'com.facebook.react:react-native:+'
58
+ implementation 'com.margelo.nitro:nitro-modules:+'
59
+ implementation 'com.facebook.android:facebook-android-sdk:17.+'
60
+ }
@@ -0,0 +1,139 @@
1
+ package com.nitrofbanalytics
2
+
3
+ import android.os.Bundle
4
+ import com.facebook.FacebookSdk
5
+ import com.facebook.appevents.AppEventsConstants
6
+ import com.facebook.appevents.AppEventsLogger
7
+ import com.facebook.internal.AttributionIdentifiers
8
+ import com.margelo.nitro.core.Promise
9
+ import java.math.BigDecimal
10
+ import java.util.Currency
11
+
12
+ class HybridFacebookAnalytics : HybridFacebookAnalyticsSpec() {
13
+
14
+ private val logger: AppEventsLogger by lazy {
15
+ AppEventsLogger.newLogger(FacebookSdk.getApplicationContext())
16
+ }
17
+
18
+ // region Event Logging
19
+
20
+ override fun logEvent(eventName: String, valueToSum: Double, params: Map<String, String>) {
21
+ val bundle = mapToBundle(params)
22
+ logger.logEvent(eventName, valueToSum, bundle)
23
+ }
24
+
25
+ override fun logEventWithoutParams(eventName: String, valueToSum: Double) {
26
+ if (valueToSum != 0.0) {
27
+ logger.logEvent(eventName, valueToSum)
28
+ } else {
29
+ logger.logEvent(eventName)
30
+ }
31
+ }
32
+
33
+ override fun logPurchase(amount: Double, currency: String, params: Map<String, String>) {
34
+ val bundle = mapToBundle(params)
35
+ logger.logPurchase(
36
+ BigDecimal.valueOf(amount),
37
+ Currency.getInstance(currency),
38
+ bundle
39
+ )
40
+ }
41
+
42
+ override fun logPushNotificationOpen(payload: Map<String, String>) {
43
+ val bundle = mapToBundle(payload)
44
+ logger.logPushNotificationOpen(bundle)
45
+ }
46
+
47
+ // endregion
48
+
49
+ // region User Identity
50
+
51
+ override fun setUserID(userID: String) {
52
+ AppEventsLogger.setUserID(userID)
53
+ }
54
+
55
+ override fun clearUserID() {
56
+ AppEventsLogger.clearUserID()
57
+ }
58
+
59
+ override fun getUserID(): String? {
60
+ return AppEventsLogger.getUserID()
61
+ }
62
+
63
+ override fun setUserData(
64
+ email: String?,
65
+ firstName: String?,
66
+ lastName: String?,
67
+ phone: String?,
68
+ dateOfBirth: String?,
69
+ gender: String?,
70
+ city: String?,
71
+ state: String?,
72
+ zip: String?,
73
+ country: String?
74
+ ) {
75
+ AppEventsLogger.setUserData(
76
+ email, firstName, lastName, phone,
77
+ dateOfBirth, gender, city, state, zip, country
78
+ )
79
+ }
80
+
81
+ // endregion
82
+
83
+ // region Device Identifiers
84
+
85
+ override fun getAnonymousID(): Promise<String?> {
86
+ return Promise.resolved(logger.anonymousAppDeviceGUID)
87
+ }
88
+
89
+ override fun getAdvertiserID(): Promise<String?> {
90
+ return try {
91
+ val context = FacebookSdk.getApplicationContext()
92
+ val identifiers = AttributionIdentifiers.getAttributionIdentifiers(context)
93
+ Promise.resolved(identifiers?.androidAdvertiserId)
94
+ } catch (e: Exception) {
95
+ Promise.resolved(null)
96
+ }
97
+ }
98
+
99
+ // endregion
100
+
101
+ // region Configuration
102
+
103
+ override fun setFlushBehavior(flushBehavior: String) {
104
+ when (flushBehavior) {
105
+ "explicit_only" -> AppEventsLogger.setFlushBehavior(AppEventsLogger.FlushBehavior.EXPLICIT_ONLY)
106
+ else -> AppEventsLogger.setFlushBehavior(AppEventsLogger.FlushBehavior.AUTO)
107
+ }
108
+ }
109
+
110
+ override fun flush() {
111
+ logger.flush()
112
+ }
113
+
114
+ // endregion
115
+
116
+ // region Push Notifications
117
+
118
+ override fun setPushNotificationsDeviceToken(token: String) {
119
+ // No-op on Android — use setPushNotificationsRegistrationId instead
120
+ }
121
+
122
+ override fun setPushNotificationsRegistrationId(registrationId: String) {
123
+ AppEventsLogger.setPushNotificationsRegistrationId(registrationId)
124
+ }
125
+
126
+ // endregion
127
+
128
+ // region Helpers
129
+
130
+ private fun mapToBundle(map: Map<String, String>): Bundle {
131
+ val bundle = Bundle()
132
+ for ((key, value) in map) {
133
+ bundle.putString(key, value)
134
+ }
135
+ return bundle
136
+ }
137
+
138
+ // endregion
139
+ }
package/app.plugin.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require("./plugin/build").default;
@@ -0,0 +1,31 @@
1
+ require 'json'
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
+
5
+ nitrogen_autolinking = File.join(__dir__, 'nitrogen', 'generated', 'ios', 'NitroFBAnalytics+autolinking.rb')
6
+
7
+ Pod::Spec.new do |s|
8
+ s.name = 'expo-facebook-analytics'
9
+ s.version = package['version']
10
+ s.summary = package['description']
11
+ s.homepage = 'https://github.com/user/expo-facebook-analytics'
12
+ s.license = package['license']
13
+ s.author = 'expo-facebook-analytics contributors'
14
+ s.source = { :git => '.', :tag => s.version.to_s }
15
+ s.platforms = { :ios => '13.0' }
16
+ s.module_name = 'NitroFBAnalytics'
17
+
18
+ s.source_files = [
19
+ 'ios/**/*.{swift,h,hpp,m,mm,cpp}',
20
+ ]
21
+
22
+ s.dependency 'React-Core'
23
+ s.dependency 'FBSDKCoreKit', '~> 17.0'
24
+
25
+ s.frameworks = ['AdSupport']
26
+
27
+ if File.exist?(nitrogen_autolinking)
28
+ load nitrogen_autolinking
29
+ add_nitrogen_files(s)
30
+ end
31
+ end
@@ -0,0 +1,135 @@
1
+ import Foundation
2
+ import NitroModules
3
+ import FBSDKCoreKit
4
+ import AdSupport
5
+
6
+ class HybridFacebookAnalytics: HybridFacebookAnalyticsSpec {
7
+
8
+ // MARK: - Event Logging
9
+
10
+ func logEvent(eventName: String, valueToSum: Double, params: [String: String]) throws {
11
+ let fbParams: [AppEvents.ParameterName: Any] = params.reduce(into: [:]) { result, pair in
12
+ result[AppEvents.ParameterName(pair.key)] = pair.value
13
+ }
14
+ AppEvents.shared.logEvent(
15
+ AppEvents.Name(eventName),
16
+ valueToSum: valueToSum,
17
+ parameters: fbParams
18
+ )
19
+ }
20
+
21
+ func logEventWithoutParams(eventName: String, valueToSum: Double) throws {
22
+ if valueToSum != 0 {
23
+ AppEvents.shared.logEvent(
24
+ AppEvents.Name(eventName),
25
+ valueToSum: valueToSum
26
+ )
27
+ } else {
28
+ AppEvents.shared.logEvent(AppEvents.Name(eventName))
29
+ }
30
+ }
31
+
32
+ func logPurchase(amount: Double, currency: String, params: [String: String]) throws {
33
+ let fbParams: [AppEvents.ParameterName: Any] = params.reduce(into: [:]) { result, pair in
34
+ result[AppEvents.ParameterName(pair.key)] = pair.value
35
+ }
36
+ AppEvents.shared.logPurchase(amount: amount, currency: currency, parameters: fbParams)
37
+ }
38
+
39
+ func logPushNotificationOpen(payload: [String: String]) throws {
40
+ let nsPayload: [String: Any] = payload.reduce(into: [:]) { result, pair in
41
+ result[pair.key] = pair.value
42
+ }
43
+ AppEvents.shared.logPushNotificationOpen(payload: nsPayload)
44
+ }
45
+
46
+ // MARK: - User Identity
47
+
48
+ func setUserID(userID: String) throws {
49
+ AppEvents.shared.userID = userID
50
+ }
51
+
52
+ func clearUserID() throws {
53
+ AppEvents.shared.userID = nil
54
+ }
55
+
56
+ func getUserID() throws -> String? {
57
+ return AppEvents.shared.userID
58
+ }
59
+
60
+ func setUserData(
61
+ email: String?,
62
+ firstName: String?,
63
+ lastName: String?,
64
+ phone: String?,
65
+ dateOfBirth: String?,
66
+ gender: String?,
67
+ city: String?,
68
+ state: String?,
69
+ zip: String?,
70
+ country: String?
71
+ ) throws {
72
+ AppEvents.shared.setUser(
73
+ email: email,
74
+ firstName: firstName,
75
+ lastName: lastName,
76
+ phone: phone,
77
+ dateOfBirth: dateOfBirth,
78
+ gender: gender,
79
+ city: city,
80
+ state: state,
81
+ zip: zip,
82
+ country: country
83
+ )
84
+ }
85
+
86
+ // MARK: - Device Identifiers
87
+
88
+ func getAnonymousID() throws -> Promise<String?> {
89
+ return Promise.resolved(withResult: AppEvents.shared.anonymousID)
90
+ }
91
+
92
+ func getAdvertiserID() throws -> Promise<String?> {
93
+ let idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
94
+ if idfa == "00000000-0000-0000-0000-000000000000" {
95
+ return Promise.resolved(withResult: nil)
96
+ }
97
+ return Promise.resolved(withResult: idfa)
98
+ }
99
+
100
+ // MARK: - Configuration
101
+
102
+ func setFlushBehavior(flushBehavior: String) throws {
103
+ switch flushBehavior {
104
+ case "explicit_only":
105
+ AppEvents.shared.flushBehavior = .explicitOnly
106
+ default:
107
+ AppEvents.shared.flushBehavior = .auto
108
+ }
109
+ }
110
+
111
+ func flush() throws {
112
+ AppEvents.shared.flush()
113
+ }
114
+
115
+ // MARK: - Push Notifications
116
+
117
+ func setPushNotificationsDeviceToken(token: String) throws {
118
+ // Token comes as a hex string — convert back to raw Data
119
+ let hex = token.replacingOccurrences(of: " ", with: "")
120
+ var data = Data()
121
+ var index = hex.startIndex
122
+ while index < hex.endIndex {
123
+ let nextIndex = hex.index(index, offsetBy: 2)
124
+ if let byte = UInt8(hex[index..<nextIndex], radix: 16) {
125
+ data.append(byte)
126
+ }
127
+ index = nextIndex
128
+ }
129
+ AppEvents.shared.setPushNotificationsDeviceToken(data)
130
+ }
131
+
132
+ func setPushNotificationsRegistrationId(registrationId: String) throws {
133
+ // No-op on iOS — this is an Android-only method
134
+ }
135
+ }
package/lib/index.d.ts ADDED
@@ -0,0 +1,58 @@
1
+ import type { AppEventsFlushBehavior, Params, UserData } from "./types";
2
+ export type { AppEventsFlushBehavior, Params, UserData } from "./types";
3
+ export { AppEventParams, AppEvents } from "./types";
4
+ /**
5
+ * Log a custom or predefined app event.
6
+ * @param eventName - Event name (use AppEvents constants for predefined events)
7
+ * @param args - Optional valueToSum (number) and/or params object
8
+ */
9
+ export declare function logEvent(eventName: string, ...args: Array<number | Params>): void;
10
+ /**
11
+ * Log a purchase event.
12
+ */
13
+ export declare function logPurchase(purchaseAmount: number, currencyCode: string, parameters?: Params): void;
14
+ /**
15
+ * Log a push notification open event.
16
+ */
17
+ export declare function logPushNotificationOpen(payload?: Record<string, string | number>): void;
18
+ /**
19
+ * Set the user ID for analytics association.
20
+ */
21
+ export declare function setUserID(userID: string | null): void;
22
+ /**
23
+ * Clear the current user ID.
24
+ */
25
+ export declare function clearUserID(): void;
26
+ /**
27
+ * Get the current user ID.
28
+ */
29
+ export declare function getUserID(): string | undefined;
30
+ /**
31
+ * Set user data for advanced matching.
32
+ */
33
+ export declare function setUserData(userData: UserData): void;
34
+ /**
35
+ * Get the anonymous device ID.
36
+ */
37
+ export declare function getAnonymousID(): Promise<string | undefined>;
38
+ /**
39
+ * Get the advertiser ID (IDFA on iOS, AAID on Android).
40
+ */
41
+ export declare function getAdvertiserID(): Promise<string | undefined>;
42
+ /**
43
+ * Set the flush behavior for event batching.
44
+ * @param flushBehavior - 'auto' or 'explicit_only'
45
+ */
46
+ export declare function setFlushBehavior(flushBehavior: AppEventsFlushBehavior): void;
47
+ /**
48
+ * Flush all queued events to Facebook immediately.
49
+ */
50
+ export declare function flush(): void;
51
+ /**
52
+ * Set the push notification device token (iOS).
53
+ */
54
+ export declare function setPushNotificationsDeviceToken(deviceToken: string): void;
55
+ /**
56
+ * Set the push notification registration ID (Android/FCM).
57
+ */
58
+ export declare function setPushNotificationsRegistrationId(registrationId: string): void;