@apex-inc/capacitor-plugin 2.5.1 → 2.6.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.
@@ -11,6 +11,7 @@ Pod::Spec.new do |s|
11
11
  s.author = package['author']
12
12
  s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
13
13
  s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
14
+ s.resource_bundles = { 'ApexIncCapacitorPluginPrivacy' => ['ios/Sources/PrivacyInfo.xcprivacy'] }
14
15
  s.ios.deployment_target = '13.0'
15
16
  s.dependency 'Capacitor'
16
17
  s.swift_version = '5.9'
package/README.md CHANGED
@@ -29,6 +29,8 @@ await Apex.initialize({
29
29
  // apiUrl: "https://app.apex.inc",
30
30
  // autoTrackScreenViews: true, // default — screen_view auto-fires from SPA navigation
31
31
  // autoConversionValues: true, // default — Apex drives SKAdNetwork values from Set up Apex (iOS)
32
+ // autoTrackInstall: true, // default — app_install once, on the first launch of a fresh install
33
+ // metaAppId: "1234567890", // Android: credits installs from Meta ads (see "Meta install referrer")
32
34
  // sessionTimeoutMinutes: 30,
33
35
  // offlineQueueMaxSize: 1000,
34
36
  // testMode: false,
@@ -36,7 +38,17 @@ await Apex.initialize({
36
38
  });
37
39
  ```
38
40
 
39
- `app_open` auto-fires on `initialize()`. `screen_view` auto-fires from
41
+ On iOS and Android the plugin sends `app_install` itself, once, on the
42
+ first launch of a fresh install, carrying what Apex needs to credit the
43
+ ad behind it. Someone who had your app before you added Apex is not sent
44
+ as an install. If your app already tracks `app_install`, keep it or
45
+ remove it: only the first one per install is sent.
46
+
47
+ Track `app_open` yourself on launch and when the app returns to the
48
+ foreground; on iOS and Android the plugin does not send it for you. (In a
49
+ browser preview, the web version sends one `app_open` per page load.)
50
+
51
+ `screen_view` auto-fires from
40
52
  the webview's History API (pushState / replaceState / back-forward /
41
53
  hashchange — covers Ionic, React Router, Vue Router, and plain SPA
42
54
  routing, on device and in browser preview). Screen names default to the
@@ -169,6 +181,27 @@ const { status: current } = await Apex.getTrackingStatus();
169
181
 
170
182
  ## Advertising identifiers
171
183
 
184
+ Every event carries the phone's details under `mobile` (app id, app
185
+ version, OS version, model, language, time zone, and on iOS the tracking
186
+ answer). Apex passes them to the ad networks you connect, so they can
187
+ credit installs and purchases to their ads. The advertising id rides
188
+ along only with permission:
189
+
190
+ - **iOS**: the IDFA, only after the person allowed tracking in the ATT
191
+ prompt. Read on every event, so a change in Settings applies at once.
192
+ - **Android**: the GAID, only when the person has not limited ad tracking
193
+ or deleted the id. Looked up at `initialize()` and again when the app
194
+ opens.
195
+
196
+ The plugin ships an Apple privacy manifest that declares the advertising
197
+ id, app activity and purchases as used for tracking, since Apex sends
198
+ installs and purchases to the ad networks you connect. Xcode merges it into your app's privacy report;
199
+ your App Store privacy label should say the same.
200
+
201
+ The IDFV and Android ID fallbacks below are never put on events. If your
202
+ app asks for consent with `requireConsent`, nothing is sent at all until
203
+ `setConsent({ granted: true })`.
204
+
172
205
  ```ts
173
206
  // Returns IDFA (iOS, ATT authorized), GAID (Android), or fallback.
174
207
  const { id, fallback } = await Apex.getAdvertisingId();
@@ -177,6 +210,24 @@ if (!id && fallback === "idfv") {
177
210
  }
178
211
  ```
179
212
 
213
+ ## Meta install referrer (Android)
214
+
215
+ The Facebook, Instagram and Facebook Lite apps remember the Meta ad a
216
+ person tapped or saw before installing yours. Pass your Meta app id and
217
+ the install carries that ad to Apex:
218
+
219
+ ```ts
220
+ await Apex.initialize({ workspaceKey: "prj_your_key", metaAppId: "1234567890" });
221
+ ```
222
+
223
+ Skip `metaAppId` if your app already has the Facebook SDK's
224
+ `com.facebook.sdk.ApplicationId` manifest entry; the plugin reads it.
225
+ The ad stays encrypted on the phone. Apex opens it with your install
226
+ referrer key: in Meta for Developers, open your app's Basic settings,
227
+ find "Install Referrer Decryption Key" under Android, and paste it in
228
+ Apex under the Meta connection. Needs Facebook 428, Instagram 296 or
229
+ Facebook Lite 411 or newer on the phone.
230
+
180
231
  ## SKAdNetwork conversion values (iOS 4.0+)
181
232
 
182
233
  You do not have to write this code. In the Apex dashboard, **Set up Apex →
@@ -36,5 +36,10 @@
36
36
  <package android:name="com.google.android.feedback" />
37
37
  <package android:name="com.amazon.venezia" />
38
38
  <package android:name="com.sec.android.app.samsungapps" />
39
+ <!-- Meta Install Referrer: Android 11+ hides these apps' content
40
+ providers unless the app declares it looks for them. -->
41
+ <package android:name="com.facebook.katana" />
42
+ <package android:name="com.instagram.android" />
43
+ <package android:name="com.facebook.lite" />
39
44
  </queries>
40
45
  </manifest>
@@ -67,9 +67,19 @@ class ApexCapacitorPlugin : Plugin() {
67
67
  // rather than returning null because the Play service hasn't
68
68
  // connected yet. Calls that arrive before the fetch completes are
69
69
  // parked and flushed by the listener.
70
- private var installReferrerResolved: Boolean = false
70
+ @Volatile private var installReferrerResolved: Boolean = false
71
71
  private var installReferrerClickSeconds: Long = 0
72
72
  private val pendingReferrerCalls = mutableListOf<PluginCall>()
73
+ private val referrerLatch = java.util.concurrent.CountDownLatch(1)
74
+
75
+ // The install is sent once per install, by the plugin or the app, never both.
76
+ private var autoTrackInstall: Boolean = true
77
+ private val installLock = Any()
78
+
79
+ // Meta Install Referrer. Read once per launch, on the install event.
80
+ private var metaAppId: String? = null
81
+ @Volatile private var metaReferrerRead: Boolean = false
82
+ @Volatile private var metaReferrer: MetaInstallReferrer.Found? = null
73
83
  // Phase 2-SDK — workspace-bound SDK key forwarded as
74
84
  // `x-apex-api-key` on every event POST + on `identify()`.
75
85
  private var apiKey: String? = null
@@ -85,6 +95,27 @@ class ApexCapacitorPlugin : Plugin() {
85
95
  // Phase 4a — consent gate. Defaults granted; set false by
86
96
  // initialize({ requireConsent: true }) until setConsent({ granted:true }).
87
97
  private var consentGranted: Boolean = true
98
+
99
+ // The GAID, looked up off the main thread (Play services blocks) and
100
+ // refreshed on `app_open`, since the person can limit ad tracking or
101
+ // delete the id in Settings at any time.
102
+ @Volatile private var gaid: String? = null
103
+ @Volatile private var gaidResolved: Boolean = false
104
+ private val device by lazy {
105
+ val locale = Locale.getDefault()
106
+ MobileContext.Device(
107
+ bundleId = context.packageName,
108
+ appVersion = try {
109
+ context.packageManager.getPackageInfo(context.packageName, 0).versionName ?: "0.0.0"
110
+ } catch (_: Exception) {
111
+ "0.0.0"
112
+ },
113
+ osVersion = Build.VERSION.RELEASE,
114
+ deviceModel = "${Build.MANUFACTURER} ${Build.MODEL}".trim(),
115
+ timezone = TimeZone.getDefault().id,
116
+ locale = "${locale.language}-${locale.country}",
117
+ )
118
+ }
88
119
  // Phase 3 — per-launch dedup so each (experiment, variant) exposure fires
89
120
  // once. Concurrent set: getVariant resolves on background threads.
90
121
  private val firedExposures = java.util.concurrent.ConcurrentHashMap.newKeySet<String>()
@@ -156,6 +187,8 @@ class ApexCapacitorPlugin : Plugin() {
156
187
  apiKey = if (rawKey.isNullOrEmpty()) null else rawKey
157
188
  // Phase 4a — consent gate.
158
189
  consentGranted = !(call.getBoolean("requireConsent", false) ?: false)
190
+ metaAppId = MetaInstallReferrer.normalizeAppId(call.getString("metaAppId")) ?: manifestMetaAppId()
191
+ autoTrackInstall = call.getBoolean("autoTrackInstall", true) ?: true
159
192
  val maxSize = call.getInt("offlineQueueMaxSize") ?: 1000
160
193
 
161
194
  val queueFile = File(context.filesDir, "apex-capacitor/events.json")
@@ -210,10 +243,80 @@ class ApexCapacitorPlugin : Plugin() {
210
243
 
211
244
  // Fire-and-forget install referrer retrieval on init.
212
245
  fetchInstallReferrer()
246
+ Thread { resolveGaid() }.start()
247
+ // Off this thread: the install waits up to REFERRER_WAIT_MS for Play.
248
+ Thread { sendInstallIfFirstLaunch() }.start()
213
249
 
214
250
  call.resolve()
215
251
  }
216
252
 
253
+ /** First install time and this version's install time, from the package manager. */
254
+ private fun installTimes(): Pair<Long?, Long?> = try {
255
+ val info = context.packageManager.getPackageInfo(context.packageName, 0)
256
+ Pair(info.firstInstallTime, info.lastUpdateTime)
257
+ } catch (_: Exception) {
258
+ Pair(null, null)
259
+ }
260
+
261
+ /**
262
+ * Send `app_install` on the first launch of a fresh install. Marks the
263
+ * install as handled for someone who had the app before Apex, so the
264
+ * update that adds Apex reports no one as new.
265
+ */
266
+ private fun sendInstallIfFirstLaunch() {
267
+ if (!autoTrackInstall || !consentGranted || offlineQueue == null) return
268
+ val (installed, versionInstalled) = installTimes()
269
+ val decision = synchronized(installLock) {
270
+ val sent = prefs?.getBoolean(FirstLaunchInstall.PREF_KEY, false) == true
271
+ val d = FirstLaunchInstall.decide(sent, installed, versionInstalled, System.currentTimeMillis())
272
+ if (d != FirstLaunchInstall.Decision.ALREADY_SENT) {
273
+ prefs?.edit()?.putBoolean(FirstLaunchInstall.PREF_KEY, true)?.apply()
274
+ }
275
+ d
276
+ }
277
+ if (debug) println("[apex-capacitor] first-launch install: $decision")
278
+ if (decision != FirstLaunchInstall.Decision.SEND) return
279
+ try {
280
+ enqueuePayload(
281
+ UUID.randomUUID().toString().lowercase(),
282
+ mutableMapOf<String, Any?>("type" to "app_install", "data" to JSONObject().put("source", "apex_first_launch")),
283
+ )
284
+ } catch (e: Exception) {
285
+ if (debug) println("[apex-capacitor] first-launch install not queued: ${e.message}")
286
+ }
287
+ }
288
+
289
+ /** True the first time an install is claimed; the app's own `app_install` after that is dropped. */
290
+ private fun claimInstall(): Boolean = synchronized(installLock) {
291
+ if (prefs?.getBoolean(FirstLaunchInstall.PREF_KEY, false) == true) {
292
+ false
293
+ } else {
294
+ prefs?.edit()?.putBoolean(FirstLaunchInstall.PREF_KEY, true)?.apply()
295
+ true
296
+ }
297
+ }
298
+
299
+ private fun resolveGaid() {
300
+ if (Looper.myLooper() == Looper.getMainLooper()) return
301
+ gaid = try {
302
+ val info = AdvertisingIdClient.getAdvertisingIdInfo(context)
303
+ MobileContext.advertisingId(info.id, info.isLimitAdTrackingEnabled)
304
+ } catch (_: Exception) {
305
+ null
306
+ }
307
+ gaidResolved = true
308
+ }
309
+
310
+ /** The first event of a launch (often the install) waits for the lookup rather than going without. */
311
+ private fun currentGaid(): String? {
312
+ if (!gaidResolved) resolveGaid()
313
+ return gaid
314
+ }
315
+
316
+ private fun stampDevice(slot: MutableMap<String, Any?>) {
317
+ MobileContext.fill(slot, device, currentGaid())
318
+ }
319
+
217
320
  // ── Push notifications (FCM) ──────────────────────────────────────
218
321
  @PluginMethod
219
322
  fun registerForPushNotifications(call: PluginCall) {
@@ -812,7 +915,7 @@ class ApexCapacitorPlugin : Plugin() {
812
915
  payload["mobile"] = mutableMapOf<String, Any?>(
813
916
  "releaseChannel" to releaseChannel,
814
917
  "releaseChannelSource" to releaseChannelSource,
815
- )
918
+ ).also { stampDevice(it) }
816
919
  val event = NativeQueuedEvent(
817
920
  id = UUID.randomUUID().toString().lowercase(),
818
921
  payload = payload,
@@ -902,8 +1005,7 @@ class ApexCapacitorPlugin : Plugin() {
902
1005
  // ── Events / Queue ────────────────────────────────────────────────
903
1006
  @PluginMethod
904
1007
  fun track(call: PluginCall) {
905
- val queue = offlineQueue
906
- if (queue == null) {
1008
+ if (offlineQueue == null) {
907
1009
  call.reject("Plugin not initialized — call initialize() first")
908
1010
  return
909
1011
  }
@@ -916,6 +1018,22 @@ class ApexCapacitorPlugin : Plugin() {
916
1018
  val id = call.getString("id") ?: UUID.randomUUID().toString().lowercase()
917
1019
  val payload = mutableMapOf<String, Any?>()
918
1020
  call.data.keys().forEach { key -> payload[key] = call.data.opt(key) }
1021
+ if (payload["type"] == "app_install" && !claimInstall()) {
1022
+ if (debug) println("[apex-capacitor] app_install already sent for this install; dropping")
1023
+ call.resolve()
1024
+ return
1025
+ }
1026
+ try {
1027
+ enqueuePayload(id, payload)
1028
+ call.resolve()
1029
+ } catch (e: Exception) {
1030
+ call.reject("Failed to enqueue event: ${e.message}")
1031
+ }
1032
+ }
1033
+
1034
+ /** Stamp and queue an event. Shared by `track()` and the plugin's own install. */
1035
+ private fun enqueuePayload(id: String, payload: MutableMap<String, Any?>) {
1036
+ val queue = offlineQueue ?: throw IllegalStateException("Plugin not initialized")
919
1037
  TrackStamps.apply(payload, visitorId, testMode, java.time.Instant.now().toString())
920
1038
 
921
1039
  // MMP-061 — stamp release channel under event.mobile so the
@@ -934,7 +1052,10 @@ class ApexCapacitorPlugin : Plugin() {
934
1052
  }
935
1053
  mobileSlot["releaseChannel"] = releaseChannel
936
1054
  mobileSlot["releaseChannelSource"] = releaseChannelSource
1055
+ stampDevice(mobileSlot)
1056
+ if (payload["type"] == "app_install") stampInstallReferrers(mobileSlot)
937
1057
  payload["mobile"] = mobileSlot
1058
+ if (payload["type"] == "app_open") Thread { resolveGaid() }.start()
938
1059
 
939
1060
  // MMP-081 — runtime context. Native Android plugin always
940
1061
  // stamps `native-android`; we don't overwrite a value the
@@ -951,13 +1072,8 @@ class ApexCapacitorPlugin : Plugin() {
951
1072
  attempts = 0,
952
1073
  enqueuedAtMs = System.currentTimeMillis(),
953
1074
  )
954
- try {
955
- queue.enqueue(event)
956
- kickFlush("track")
957
- call.resolve()
958
- } catch (e: Exception) {
959
- call.reject("Failed to enqueue event: ${e.message}")
960
- }
1075
+ queue.enqueue(event)
1076
+ kickFlush("track")
961
1077
  }
962
1078
 
963
1079
  @PluginMethod
@@ -1010,6 +1126,7 @@ class ApexCapacitorPlugin : Plugin() {
1010
1126
  if (granted) {
1011
1127
  // Resume: flush anything captured before this point.
1012
1128
  kickFlush("consent")
1129
+ Thread { sendInstallIfFirstLaunch() }.start()
1013
1130
  } else {
1014
1131
  // Revoke: drop anything queued but not yet sent.
1015
1132
  try {
@@ -1108,8 +1225,71 @@ class ApexCapacitorPlugin : Plugin() {
1108
1225
  })
1109
1226
  }
1110
1227
 
1228
+ /**
1229
+ * The install event carries Play's referrer and Meta's, so Apex can
1230
+ * credit the ad. Waits briefly for Play when it hasn't answered yet,
1231
+ * off the main thread only.
1232
+ */
1233
+ private fun stampInstallReferrers(slot: MutableMap<String, Any?>) {
1234
+ if (!installReferrerResolved && Looper.myLooper() != Looper.getMainLooper()) {
1235
+ try {
1236
+ referrerLatch.await(REFERRER_WAIT_MS, java.util.concurrent.TimeUnit.MILLISECONDS)
1237
+ } catch (_: InterruptedException) { }
1238
+ }
1239
+ MetaInstallReferrer.stampInstall(slot, lastInstallReferrer, installReferrerClickSeconds, readMetaReferrer())
1240
+ }
1241
+
1242
+ /** The Meta app id from the Facebook SDK's manifest entry, when the app has one. */
1243
+ @Suppress("DEPRECATION")
1244
+ private fun manifestMetaAppId(): String? = try {
1245
+ val info = context.packageManager.getApplicationInfo(
1246
+ context.packageName,
1247
+ android.content.pm.PackageManager.GET_META_DATA,
1248
+ )
1249
+ MetaInstallReferrer.normalizeAppId(info.metaData?.get("com.facebook.sdk.ApplicationId")?.toString())
1250
+ } catch (_: Exception) {
1251
+ null
1252
+ }
1253
+
1254
+ /** Ask the Facebook, Instagram and Facebook Lite apps for the Meta ad behind this install. */
1255
+ private fun readMetaReferrer(): MetaInstallReferrer.Found? {
1256
+ if (metaReferrerRead) return metaReferrer
1257
+ val appId = metaAppId
1258
+ if (appId == null) {
1259
+ metaReferrerRead = true
1260
+ return null
1261
+ }
1262
+ val found = mutableListOf<MetaInstallReferrer.Found>()
1263
+ for ((authority, app) in MetaInstallReferrer.PROVIDERS) {
1264
+ try {
1265
+ if (context.packageManager.resolveContentProvider(authority, 0) == null) continue
1266
+ val uri = Uri.parse("content://$authority/$appId")
1267
+ context.contentResolver.query(uri, MetaInstallReferrer.COLUMNS, null, null, null)?.use { c ->
1268
+ if (!c.moveToFirst()) return@use
1269
+ val refIdx = c.getColumnIndex("install_referrer")
1270
+ if (refIdx < 0 || c.isNull(refIdx)) return@use
1271
+ val ctIdx = c.getColumnIndex("is_ct")
1272
+ val tsIdx = c.getColumnIndex("actual_timestamp")
1273
+ found += MetaInstallReferrer.Found(
1274
+ referrer = c.getString(refIdx),
1275
+ isClickThrough = if (ctIdx >= 0 && !c.isNull(ctIdx)) c.getInt(ctIdx) == 1 else null,
1276
+ timestampSeconds = if (tsIdx >= 0 && !c.isNull(tsIdx)) c.getLong(tsIdx) else null,
1277
+ app = app,
1278
+ )
1279
+ }
1280
+ } catch (e: Exception) {
1281
+ if (debug) println("[apex-capacitor] Meta referrer from $app failed: ${e.message}")
1282
+ }
1283
+ }
1284
+ metaReferrer = MetaInstallReferrer.latest(found)
1285
+ metaReferrerRead = true
1286
+ if (debug) println("[apex-capacitor] Meta install referrer ${if (metaReferrer != null) "found (${metaReferrer?.app})" else "not found"}")
1287
+ return metaReferrer
1288
+ }
1289
+
1111
1290
  private fun flushPendingReferrerCalls() {
1112
1291
  installReferrerResolved = true
1292
+ referrerLatch.countDown()
1113
1293
  val waiting = synchronized(pendingReferrerCalls) {
1114
1294
  val copy = pendingReferrerCalls.toList()
1115
1295
  pendingReferrerCalls.clear()
@@ -0,0 +1,28 @@
1
+ package inc.apex.capacitor
2
+
3
+ /**
4
+ * Whether this launch should send `app_install`. The plugin sends it once
5
+ * per install so every app counts installs the same way; the app's own
6
+ * `app_install` is dropped once one has gone.
7
+ *
8
+ * Someone who had the app before Apex was added is not a new install: the
9
+ * update that brings Apex must not report every existing user to the ad
10
+ * networks as one. A fresh install is one made in the last 7 days, or one
11
+ * never updated since (the version installed is the one running).
12
+ */
13
+ internal object FirstLaunchInstall {
14
+ const val PREF_KEY = "installSent"
15
+ const val FRESH_WINDOW_MS: Long = 7L * 24 * 3600 * 1000
16
+ private const val SAME_VERSION_TOLERANCE_MS: Long = 5L * 60 * 1000
17
+
18
+ enum class Decision { SEND, ALREADY_SENT, EXISTING_USER }
19
+
20
+ fun decide(alreadySent: Boolean, installedMs: Long?, versionInstalledMs: Long?, nowMs: Long): Decision {
21
+ if (alreadySent) return Decision.ALREADY_SENT
22
+ if (installedMs == null || installedMs <= 0) return Decision.SEND
23
+ if (versionInstalledMs != null && kotlin.math.abs(versionInstalledMs - installedMs) <= SAME_VERSION_TOLERANCE_MS) {
24
+ return Decision.SEND
25
+ }
26
+ return if (nowMs - installedMs <= FRESH_WINDOW_MS) Decision.SEND else Decision.EXISTING_USER
27
+ }
28
+ }
@@ -0,0 +1,75 @@
1
+ package inc.apex.capacitor
2
+
3
+ /**
4
+ * Meta Install Referrer: the Facebook, Instagram and Facebook Lite apps
5
+ * keep the Meta ad a person tapped or saw before installing, and hand it to
6
+ * the app that was installed. Play's referrer only carries a tap that led
7
+ * straight to the install; this also carries views and earlier taps.
8
+ *
9
+ * The campaign inside is encrypted with the app owner's key. The plugin
10
+ * never decrypts it; it goes to Apex on the `app_install` event and Apex
11
+ * opens it with the key the shop saved in the Meta connection.
12
+ *
13
+ * Pure logic here (no Android imports) so it runs under plain JUnit. The
14
+ * ContentResolver query lives in the plugin.
15
+ */
16
+ internal object MetaInstallReferrer {
17
+
18
+ /** Content provider authority → the app name Apex records. */
19
+ val PROVIDERS: List<Pair<String, String>> = listOf(
20
+ "com.facebook.katana.provider.InstallReferrerProvider" to "facebook",
21
+ "com.instagram.contentprovider.InstallReferrerProvider" to "instagram",
22
+ "com.facebook.lite.provider.InstallReferrerProvider" to "facebook_lite",
23
+ )
24
+
25
+ val COLUMNS: Array<String> = arrayOf("install_referrer", "is_ct", "actual_timestamp")
26
+
27
+ data class Found(
28
+ val referrer: String,
29
+ /** Null when the Meta app didn't say tap or view. */
30
+ val isClickThrough: Boolean?,
31
+ /** When the tap or view happened, in seconds. */
32
+ val timestampSeconds: Long?,
33
+ val app: String,
34
+ )
35
+
36
+ /**
37
+ * The Meta app id as the provider path wants it: digits only. Accepts
38
+ * the Facebook SDK's `fb1234…` form as well as the plain id.
39
+ */
40
+ fun normalizeAppId(raw: String?): String? {
41
+ val trimmed = raw?.trim()?.removePrefix("fb") ?: return null
42
+ return if (trimmed.isNotEmpty() && trimmed.all { it.isDigit() }) trimmed else null
43
+ }
44
+
45
+ /** The most recent touch wins when more than one Meta app answered. */
46
+ fun latest(found: List<Found>): Found? =
47
+ found.filter { it.referrer.isNotBlank() }.maxByOrNull { it.timestampSeconds ?: 0L }
48
+
49
+ /** What goes under `event.mobile.metaInstallReferrer`. */
50
+ fun toSlot(found: Found): Map<String, Any?> {
51
+ val slot = mutableMapOf<String, Any?>("referrer" to found.referrer, "app" to found.app)
52
+ found.isClickThrough?.let { slot["isClickThrough"] = it }
53
+ found.timestampSeconds?.let { if (it > 0) slot["timestamp"] = it }
54
+ return slot
55
+ }
56
+
57
+ /**
58
+ * Stamp the install's referrers on an `app_install` event, keeping
59
+ * anything the app already set.
60
+ */
61
+ fun stampInstall(
62
+ slot: MutableMap<String, Any?>,
63
+ playReferrer: String?,
64
+ playClickSeconds: Long,
65
+ meta: Found?,
66
+ ) {
67
+ if (slot["installReferrer"] == null && !playReferrer.isNullOrBlank()) {
68
+ slot["installReferrer"] = playReferrer
69
+ if (playClickSeconds > 0) slot["installReferrerClickTimestamp"] = playClickSeconds
70
+ }
71
+ if (slot["metaInstallReferrer"] == null && meta != null) {
72
+ slot["metaInstallReferrer"] = toSlot(meta)
73
+ }
74
+ }
75
+ }
@@ -0,0 +1,43 @@
1
+ package inc.apex.capacitor
2
+
3
+ /**
4
+ * The device details stamped under `event.mobile` on every event, matching
5
+ * iOS. Apex builds the ad networks' app-event device block from them
6
+ * (Meta's `app_data` + `extinfo`), so an event without them reaches Meta
7
+ * with a blank device.
8
+ *
9
+ * The advertising id is the GAID, and only when the person has not limited
10
+ * ad tracking. The Android ID fallback is never sent: it is not an
11
+ * advertising id and Meta must not match on it.
12
+ */
13
+ internal object MobileContext {
14
+ private const val ZERO_ID = "00000000-0000-0000-0000-000000000000"
15
+
16
+ data class Device(
17
+ val bundleId: String,
18
+ val appVersion: String,
19
+ val osVersion: String,
20
+ val deviceModel: String,
21
+ val timezone: String,
22
+ val locale: String,
23
+ )
24
+
25
+ /** The GAID to send, or null when tracking is limited or the person deleted the id. */
26
+ fun advertisingId(id: String?, limitAdTracking: Boolean): String? =
27
+ if (limitAdTracking || id.isNullOrBlank() || id == ZERO_ID) null else id.lowercase()
28
+
29
+ /** Fill the fields the caller didn't set on the event. */
30
+ fun fill(slot: MutableMap<String, Any?>, device: Device, gaid: String?) {
31
+ putIfMissing(slot, "bundleId", device.bundleId)
32
+ putIfMissing(slot, "appVersion", device.appVersion)
33
+ putIfMissing(slot, "osVersion", device.osVersion)
34
+ putIfMissing(slot, "deviceModel", device.deviceModel)
35
+ putIfMissing(slot, "timezone", device.timezone)
36
+ putIfMissing(slot, "locale", device.locale)
37
+ if (gaid != null) putIfMissing(slot, "gaid", gaid)
38
+ }
39
+
40
+ private fun putIfMissing(slot: MutableMap<String, Any?>, key: String, value: String) {
41
+ if (slot[key] == null) slot[key] = value
42
+ }
43
+ }
@@ -205,10 +205,11 @@ export interface InitializeOptions {
205
205
  * until you call `setConsent({ granted: true })` (e.g. from your privacy
206
206
  * prompt's accept handler). Default `false` (collect immediately).
207
207
  *
208
- * Apex uses a first-party visitor id, not an ad identifier (IDFA), so iOS
209
- * App Tracking Transparency is out of scope; this gate covers the consent
210
- * obligation that does apply. (See `requestTrackingAuthorization` for ATT,
211
- * which remains a separate, optional native prompt.)
208
+ * Apex counts people by a first-party visitor id. The advertising id is a
209
+ * separate permission: events carry the IDFA only after the person allows
210
+ * tracking in the ATT prompt (`requestTrackingAuthorization`), and the
211
+ * GAID only when they haven't limited ad tracking. The IDFV and Android
212
+ * ID are never put on events.
212
213
  */
213
214
  requireConsent?: boolean;
214
215
  /**
@@ -247,6 +248,26 @@ export interface InitializeOptions {
247
248
  * workspace has more than one. Defaults to the workspace's first app.
248
249
  */
249
250
  mobileAppId?: string;
251
+ /**
252
+ * Your Meta (Facebook) app id, from Meta for Developers. On Android the
253
+ * plugin uses it to ask the Facebook, Instagram and Facebook Lite apps
254
+ * which Meta ad the person tapped or saw before installing, and sends
255
+ * that with the `app_install` event. Apex opens it with the install
256
+ * referrer key saved in your Meta connection and credits the ad.
257
+ *
258
+ * Optional when your app already has the Facebook SDK's
259
+ * `com.facebook.sdk.ApplicationId` manifest entry. No-op on iOS and web.
260
+ */
261
+ metaAppId?: string;
262
+ /**
263
+ * Send `app_install` once, on the first launch of a fresh install
264
+ * (default true on iOS and Android; no-op on web). It carries what Apex
265
+ * needs to credit the ad behind the install and to report it to the ad
266
+ * networks you connect. Someone who had the app before Apex was added is
267
+ * not sent as an install. Whether the plugin or your app sends it, only
268
+ * the first `app_install` per install goes.
269
+ */
270
+ autoTrackInstall?: boolean;
250
271
  }
251
272
  /**
252
273
  * Options for {@link ApexCapacitorPlugin.identify}.
@@ -400,7 +421,8 @@ export interface ApexCapacitorPlugin {
400
421
  /**
401
422
  * Returns IDFA (iOS) or GAID (Android). When unavailable (ATT denied or LAT
402
423
  * enabled), returns a fallback with `fallback` indicating which identifier
403
- * was substituted.
424
+ * was substituted. Events never carry the fallback: they get `idfa` /
425
+ * `gaid` under `mobile` only when the real advertising id is allowed.
404
426
  */
405
427
  getAdvertisingId(): Promise<AdvertisingIdResult>;
406
428
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../src/definitions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../src/definitions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE5D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,YAAY,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAC9D,YAAY,EACV,oBAAoB,EACpB,wBAAwB,EACxB,oBAAoB,EACpB,kBAAkB,EAClB,UAAU,GACX,MAAM,0BAA0B,CAAC;AAElC,0DAA0D;AAC1D,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,QAAQ,GAAG,YAAY,GAAG,gBAAgB,CAAC;AAElF,qFAAqF;AACrF,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEpE,0EAA0E;AAC1E,MAAM,WAAW,sBAAsB;IACrC,oDAAoD;IACpD,UAAU,EAAE,oBAAoB,CAAC;IACjC;;;;;OAKG;IACH,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,4DAA4D;IAC5D,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,oCAAoC;AACpC,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,SAAS,GAAG,KAAK,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,YAAY,GACZ,WAAW,GACX,eAAe,GACf,iBAAiB,GACjB,YAAY,GACZ,SAAS,CAAC;AAEd,iDAAiD;AACjD,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,CAAC;AAEpE,8EAA8E;AAC9E,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,YAAY,GAAG,IAAI,CAAC;AAEjE,wCAAwC;AACxC,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAExD;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB;;;;;;;;;;;;;;OAcG;IACH,UAAU,CAAC,EAAE,mBAAmB,GAAG,YAAY,GAAG,gBAAgB,GAAG,aAAa,GAAG,eAAe,GAAG,QAAQ,CAAC;IAChH;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE;QACT,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,CAAC;IACF,gDAAgD;IAChD,YAAY,CAAC,EAAE;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EACF,SAAS,GACT,SAAS,GACT,WAAW,GACX,SAAS,GACT,cAAc,GACd,QAAQ,GACR,SAAS,GACT,eAAe,GACf,iBAAiB,GACjB,eAAe,CAAC;QACpB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;QACxD,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;IACF,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,0DAA0D;AAC1D,MAAM,WAAW,iBAAiB;IAChC,uDAAuD;IACvD,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8CAA8C;IAC9C,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,yEAAyE;IACzE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,qDAAqD;IACrD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;;;;;;;OAWG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;;;;;;;;;;;;OAeG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAEhC;;;;;;;;;;;;OAYG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;;;;;;OASG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;;OAOG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,oEAAoE;AACpE,MAAM,WAAW,mBAAmB;IAClC,uEAAuE;IACvE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,kEAAkE;IAClE,QAAQ,EAAE,qBAAqB,CAAC;CACjC;AAED,6EAA6E;AAC7E,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,4DAA4D;IAC5D,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAED,sCAAsC;AACtC,MAAM,WAAW,WAAW;IAC1B,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,yDAAyD;AACzD,MAAM,WAAW,WAAW;IAC1B,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,+BAA+B;AAC/B,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,uBAAuB;IACtC,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,uFAAuF;IACvF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,gFAAgF;IAChF,QAAQ,EAAE,OAAO,CAAC;IAClB,uCAAuC;IACvC,MAAM,CAAC,EAAE,gBAAgB,GAAG,SAAS,GAAG,kBAAkB,GAAG,aAAa,GAAG,WAAW,GAAG,WAAW,GAAG,YAAY,CAAC;IACtH,gDAAgD;IAChD,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAGlC;;;;OAIG;IACH,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAItD;;;OAGG;IACH,4BAA4B,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAI/D;;;;;;;;;;;;;;;OAeG;IACH,4BAA4B,IAAI,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAEhE;;;OAGG;IACH,iBAAiB,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAIpD;;;;;OAKG;IACH,gBAAgB,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAEjD;;;;;;;;;;OAUG;IACH,kBAAkB,IAAI,OAAO,CAAC;QAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC,CAAC;IAEH,0CAA0C;IAC1C,YAAY,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAE/C,+EAA+E;IAC/E,YAAY,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAI5D;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAIlD;;;;;;;;OAQG;IACH,qBAAqB,CAAC,OAAO,EAAE;QAC7B,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,eAAe,CAAC;QAC9B,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElB;;;;;OAKG;IACH,wBAAwB,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAIxD;;;;;;;;OAQG;IACH,kBAAkB,IAAI,OAAO,CAAC;QAC5B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;KAC7B,CAAC,CAAC;IAEH;;;;;;;;;;;;;;;;OAgBG;IACH,mBAAmB,IAAI,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CAAC;IAI9D,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAIrC,0DAA0D;IAC1D,YAAY,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAE/C,4CAA4C;IAC5C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B,sEAAsE;IACtE,iBAAiB,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;IAI1C;;;;;;;;;;;;;;;;OAgBG;IACH,UAAU,CAAC,OAAO,EAAE;QAClB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAErC;;;;;;;;;;;;;;;;;OAiBG;IACH,wBAAwB,CAAC,OAAO,EAAE;QAChC,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAIlE;;;;OAIG;IACH,KAAK,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvC,qEAAqE;IACrE,YAAY,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;IAErC,iFAAiF;IACjF,UAAU,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;IAInC;;;OAGG;IACH,WAAW,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1D;;;;;;OAMG;IACH,UAAU,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzD,6BAA6B;IAC7B,UAAU,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAI5C;;;;;OAKG;IACH,WAAW,CACT,SAAS,EAAE,UAAU,EACrB,YAAY,EAAE,CAAC,KAAK,EAAE;QACpB,GAAG,EAAE,MAAM,CAAC;QACZ,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;KAC7B,KAAK,IAAI,GACT,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEjC,kEAAkE;IAClE,WAAW,CACT,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EAAE,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,GACnD,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEjC,uCAAuC;IACvC,WAAW,CACT,SAAS,EAAE,cAAc,EACzB,YAAY,EAAE,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GACnD,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEjC,2CAA2C;IAC3C,WAAW,CACT,SAAS,EAAE,YAAY,EACvB,YAAY,EAAE,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GAC5E,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEjC;;;;;;OAMG;IACH,WAAW,CACT,SAAS,EAAE,mBAAmB,EAC9B,YAAY,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAA;KAAE,KAAK,IAAI,GAC5E,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEjC;;;;;;OAMG;IACH,WAAW,CACT,SAAS,EAAE,cAAc,EACzB,YAAY,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,GAC/C,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEjC;;;;;OAKG;IACH,WAAW,CACT,SAAS,EAAE,aAAa,EACxB,YAAY,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,GAC/C,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEjC,gEAAgE;IAChE,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC"}
@@ -205,10 +205,11 @@ export interface InitializeOptions {
205
205
  * until you call `setConsent({ granted: true })` (e.g. from your privacy
206
206
  * prompt's accept handler). Default `false` (collect immediately).
207
207
  *
208
- * Apex uses a first-party visitor id, not an ad identifier (IDFA), so iOS
209
- * App Tracking Transparency is out of scope; this gate covers the consent
210
- * obligation that does apply. (See `requestTrackingAuthorization` for ATT,
211
- * which remains a separate, optional native prompt.)
208
+ * Apex counts people by a first-party visitor id. The advertising id is a
209
+ * separate permission: events carry the IDFA only after the person allows
210
+ * tracking in the ATT prompt (`requestTrackingAuthorization`), and the
211
+ * GAID only when they haven't limited ad tracking. The IDFV and Android
212
+ * ID are never put on events.
212
213
  */
213
214
  requireConsent?: boolean;
214
215
  /**
@@ -247,6 +248,26 @@ export interface InitializeOptions {
247
248
  * workspace has more than one. Defaults to the workspace's first app.
248
249
  */
249
250
  mobileAppId?: string;
251
+ /**
252
+ * Your Meta (Facebook) app id, from Meta for Developers. On Android the
253
+ * plugin uses it to ask the Facebook, Instagram and Facebook Lite apps
254
+ * which Meta ad the person tapped or saw before installing, and sends
255
+ * that with the `app_install` event. Apex opens it with the install
256
+ * referrer key saved in your Meta connection and credits the ad.
257
+ *
258
+ * Optional when your app already has the Facebook SDK's
259
+ * `com.facebook.sdk.ApplicationId` manifest entry. No-op on iOS and web.
260
+ */
261
+ metaAppId?: string;
262
+ /**
263
+ * Send `app_install` once, on the first launch of a fresh install
264
+ * (default true on iOS and Android; no-op on web). It carries what Apex
265
+ * needs to credit the ad behind the install and to report it to the ad
266
+ * networks you connect. Someone who had the app before Apex was added is
267
+ * not sent as an install. Whether the plugin or your app sends it, only
268
+ * the first `app_install` per install goes.
269
+ */
270
+ autoTrackInstall?: boolean;
250
271
  }
251
272
  /**
252
273
  * Options for {@link ApexCapacitorPlugin.identify}.
@@ -400,7 +421,8 @@ export interface ApexCapacitorPlugin {
400
421
  /**
401
422
  * Returns IDFA (iOS) or GAID (Android). When unavailable (ATT denied or LAT
402
423
  * enabled), returns a fallback with `fallback` indicating which identifier
403
- * was substituted.
424
+ * was substituted. Events never carry the fallback: they get `idfa` /
425
+ * `gaid` under `mobile` only when the real advertising id is allowed.
404
426
  */
405
427
  getAdvertisingId(): Promise<AdvertisingIdResult>;
406
428
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE5D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,YAAY,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAC9D,YAAY,EACV,oBAAoB,EACpB,wBAAwB,EACxB,oBAAoB,EACpB,kBAAkB,EAClB,UAAU,GACX,MAAM,0BAA0B,CAAC;AAElC,0DAA0D;AAC1D,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,QAAQ,GAAG,YAAY,GAAG,gBAAgB,CAAC;AAElF,qFAAqF;AACrF,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEpE,0EAA0E;AAC1E,MAAM,WAAW,sBAAsB;IACrC,oDAAoD;IACpD,UAAU,EAAE,oBAAoB,CAAC;IACjC;;;;;OAKG;IACH,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,4DAA4D;IAC5D,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,oCAAoC;AACpC,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,SAAS,GAAG,KAAK,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,YAAY,GACZ,WAAW,GACX,eAAe,GACf,iBAAiB,GACjB,YAAY,GACZ,SAAS,CAAC;AAEd,iDAAiD;AACjD,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,CAAC;AAEpE,8EAA8E;AAC9E,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,YAAY,GAAG,IAAI,CAAC;AAEjE,wCAAwC;AACxC,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAExD;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB;;;;;;;;;;;;;;OAcG;IACH,UAAU,CAAC,EAAE,mBAAmB,GAAG,YAAY,GAAG,gBAAgB,GAAG,aAAa,GAAG,eAAe,GAAG,QAAQ,CAAC;IAChH;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE;QACT,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,CAAC;IACF,gDAAgD;IAChD,YAAY,CAAC,EAAE;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EACF,SAAS,GACT,SAAS,GACT,WAAW,GACX,SAAS,GACT,cAAc,GACd,QAAQ,GACR,SAAS,GACT,eAAe,GACf,iBAAiB,GACjB,eAAe,CAAC;QACpB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;QACxD,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;IACF,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,0DAA0D;AAC1D,MAAM,WAAW,iBAAiB;IAChC,uDAAuD;IACvD,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8CAA8C;IAC9C,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,yEAAyE;IACzE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,qDAAqD;IACrD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;;;;;;;OAWG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;;;;;;;;;;;;OAeG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAEhC;;;;;;;;;;;;OAYG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;;;;;;OASG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;;OAOG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,oEAAoE;AACpE,MAAM,WAAW,mBAAmB;IAClC,uEAAuE;IACvE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,kEAAkE;IAClE,QAAQ,EAAE,qBAAqB,CAAC;CACjC;AAED,6EAA6E;AAC7E,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,4DAA4D;IAC5D,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAED,sCAAsC;AACtC,MAAM,WAAW,WAAW;IAC1B,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,yDAAyD;AACzD,MAAM,WAAW,WAAW;IAC1B,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,+BAA+B;AAC/B,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,uBAAuB;IACtC,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,uFAAuF;IACvF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,gFAAgF;IAChF,QAAQ,EAAE,OAAO,CAAC;IAClB,uCAAuC;IACvC,MAAM,CAAC,EAAE,gBAAgB,GAAG,SAAS,GAAG,kBAAkB,GAAG,aAAa,GAAG,WAAW,GAAG,WAAW,GAAG,YAAY,CAAC;IACtH,gDAAgD;IAChD,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAGlC;;;;OAIG;IACH,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAItD;;;OAGG;IACH,4BAA4B,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAI/D;;;;;;;;;;;;;;;OAeG;IACH,4BAA4B,IAAI,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAEhE;;;OAGG;IACH,iBAAiB,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAIpD;;;;;OAKG;IACH,gBAAgB,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAEjD;;;;;;;;;;OAUG;IACH,kBAAkB,IAAI,OAAO,CAAC;QAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC,CAAC;IAEH,0CAA0C;IAC1C,YAAY,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAE/C,+EAA+E;IAC/E,YAAY,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAI5D;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAIlD;;;;;;;;OAQG;IACH,qBAAqB,CAAC,OAAO,EAAE;QAC7B,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,eAAe,CAAC;QAC9B,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElB;;;;;OAKG;IACH,wBAAwB,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAIxD;;;;;;;;OAQG;IACH,kBAAkB,IAAI,OAAO,CAAC;QAC5B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;KAC7B,CAAC,CAAC;IAEH;;;;;;;;;;;;;;;;OAgBG;IACH,mBAAmB,IAAI,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CAAC;IAI9D,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAIrC,0DAA0D;IAC1D,YAAY,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAE/C,4CAA4C;IAC5C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B,sEAAsE;IACtE,iBAAiB,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;IAI1C;;;;;;;;;;;;;;;;OAgBG;IACH,UAAU,CAAC,OAAO,EAAE;QAClB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAErC;;;;;;;;;;;;;;;;;OAiBG;IACH,wBAAwB,CAAC,OAAO,EAAE;QAChC,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAIlE;;;;OAIG;IACH,KAAK,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvC,qEAAqE;IACrE,YAAY,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;IAErC,iFAAiF;IACjF,UAAU,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;IAInC;;;OAGG;IACH,WAAW,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1D;;;;;;OAMG;IACH,UAAU,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzD,6BAA6B;IAC7B,UAAU,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAI5C;;;;;OAKG;IACH,WAAW,CACT,SAAS,EAAE,UAAU,EACrB,YAAY,EAAE,CAAC,KAAK,EAAE;QACpB,GAAG,EAAE,MAAM,CAAC;QACZ,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;KAC7B,KAAK,IAAI,GACT,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEjC,kEAAkE;IAClE,WAAW,CACT,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EAAE,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,GACnD,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEjC,uCAAuC;IACvC,WAAW,CACT,SAAS,EAAE,cAAc,EACzB,YAAY,EAAE,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GACnD,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEjC,2CAA2C;IAC3C,WAAW,CACT,SAAS,EAAE,YAAY,EACvB,YAAY,EAAE,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GAC5E,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEjC;;;;;;OAMG;IACH,WAAW,CACT,SAAS,EAAE,mBAAmB,EAC9B,YAAY,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAA;KAAE,KAAK,IAAI,GAC5E,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEjC;;;;;;OAMG;IACH,WAAW,CACT,SAAS,EAAE,cAAc,EACzB,YAAY,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,GAC/C,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEjC;;;;;OAKG;IACH,WAAW,CACT,SAAS,EAAE,aAAa,EACxB,YAAY,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,GAC/C,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEjC,gEAAgE;IAChE,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC"}
@@ -0,0 +1,50 @@
1
+ //
2
+ // FirstLaunchInstall.swift
3
+ // Apex Capacitor Plugin
4
+ //
5
+ // Whether this launch should send `app_install`. The plugin sends it once
6
+ // per install so every app counts installs the same way; the app's own
7
+ // `app_install` is dropped once one has gone.
8
+ //
9
+ // Someone who had the app before Apex was added is not a new install: the
10
+ // update that brings Apex must not report every existing user to the ad
11
+ // networks as one. A fresh install is one made in the last 7 days, or one
12
+ // never updated since (the version installed is the one running).
13
+ //
14
+
15
+ import Foundation
16
+
17
+ public enum FirstLaunchInstall {
18
+ public static let defaultsKey = "apex.installSent"
19
+ public static let freshWindow: TimeInterval = 7 * 24 * 3600
20
+ private static let sameVersionTolerance: TimeInterval = 5 * 60
21
+
22
+ public enum Decision: Equatable { case send, alreadySent, existingUser }
23
+
24
+ public static func decide(
25
+ alreadySent: Bool,
26
+ installedAt: Date?,
27
+ versionInstalledAt: Date?,
28
+ now: Date
29
+ ) -> Decision {
30
+ if alreadySent { return .alreadySent }
31
+ guard let installedAt = installedAt else { return .send }
32
+ if let versionInstalledAt = versionInstalledAt,
33
+ abs(versionInstalledAt.timeIntervalSince(installedAt)) <= sameVersionTolerance {
34
+ return .send
35
+ }
36
+ return now.timeIntervalSince(installedAt) <= freshWindow ? .send : .existingUser
37
+ }
38
+
39
+ /// When the app was first installed: the Documents folder is made then
40
+ /// and survives updates.
41
+ public static func installedAt() -> Date? {
42
+ guard let docs = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return nil }
43
+ return (try? FileManager.default.attributesOfItem(atPath: docs.path))?[.creationDate] as? Date
44
+ }
45
+
46
+ /// When the running version was installed: the app bundle is replaced on every update.
47
+ public static func versionInstalledAt() -> Date? {
48
+ (try? FileManager.default.attributesOfItem(atPath: Bundle.main.bundlePath))?[.creationDate] as? Date
49
+ }
50
+ }
@@ -0,0 +1,49 @@
1
+ //
2
+ // MobileContext.swift
3
+ // Apex Capacitor Plugin
4
+ //
5
+ // The device details stamped under `event.mobile` on every event. Apex
6
+ // builds the ad networks' app-event device block from them (Meta's
7
+ // `app_data` + `extinfo`), so an event without them reaches Meta with a
8
+ // blank device and tracking marked off.
9
+ //
10
+ // The advertising id is the IDFA, and only when the person allowed
11
+ // tracking. The IDFV fallback is never sent: it is not an advertising id
12
+ // and Meta must not match on it.
13
+ //
14
+
15
+ import Foundation
16
+
17
+ public enum MobileContext {
18
+ public static func fields(
19
+ device: DeviceMetadata,
20
+ att: AttStatus,
21
+ adId: AdvertisingIdResult
22
+ ) -> [String: Any] {
23
+ var fields: [String: Any] = [
24
+ "bundleId": device.bundleId,
25
+ "appVersion": device.appVersion,
26
+ "osVersion": device.osVersion,
27
+ "deviceModel": device.model,
28
+ "timezone": device.timezone,
29
+ "locale": device.locale,
30
+ "attStatus": att.rawValue,
31
+ ]
32
+ if att == .authorized, adId.fallback == nil, let idfa = adId.id {
33
+ fields["idfa"] = idfa
34
+ }
35
+ return fields
36
+ }
37
+
38
+ /// Fill the fields the caller didn't set on the event.
39
+ public static func fill(
40
+ _ slot: inout [String: Any],
41
+ device: DeviceMetadata,
42
+ att: AttStatus,
43
+ adId: AdvertisingIdResult
44
+ ) {
45
+ for (key, value) in fields(device: device, att: att, adId: adId) where slot[key] == nil {
46
+ slot[key] = value
47
+ }
48
+ }
49
+ }
@@ -55,6 +55,7 @@ public class ApexCapacitorPlugin: CAPPlugin, CAPBridgedPlugin, UNUserNotificatio
55
55
  private var attManager = AttManager()
56
56
  private var skanManager = SkanManager()
57
57
  private var deviceInfo = DeviceInfo()
58
+ private lazy var deviceMeta: DeviceMetadata = deviceInfo.collect()
58
59
  private var deepLinks = DeepLinkManager()
59
60
  private var adIds = AdvertisingIdProvider()
60
61
  private lazy var pushManager = PushNotificationManager()
@@ -101,6 +102,9 @@ public class ApexCapacitorPlugin: CAPPlugin, CAPBridgedPlugin, UNUserNotificatio
101
102
  // Phase 4a — consent gate. Defaults granted; set false by
102
103
  // initialize({ requireConsent: true }) until setConsent({ granted:true }).
103
104
  private var consentGranted = true
105
+ // The install is sent once per install, by the plugin or the app, never both.
106
+ private var autoTrackInstall = true
107
+ private let installLock = NSLock()
104
108
  // Phase 3 — per-launch dedup so each (experiment, variant) exposure
105
109
  // fires once, matching the JS/web fallback.
106
110
  private var firedExposures = Set<String>()
@@ -216,6 +220,7 @@ public class ApexCapacitorPlugin: CAPPlugin, CAPBridgedPlugin, UNUserNotificatio
216
220
  apiKey = rawKey.isEmpty ? nil : rawKey
217
221
  // Phase 4a — consent gate.
218
222
  consentGranted = !(call.getBool("requireConsent") ?? false)
223
+ autoTrackInstall = call.getBool("autoTrackInstall") ?? true
219
224
 
220
225
  // MMP-061 — release channel detection. iOS uses the receipt URL
221
226
  // + StoreKit 2 AppTransaction. Any JS-supplied override on iOS
@@ -271,10 +276,62 @@ public class ApexCapacitorPlugin: CAPPlugin, CAPBridgedPlugin, UNUserNotificatio
271
276
  self?.handleTokenArrived(token)
272
277
  }
273
278
  pushManager.silentRegisterIfAuthorized()
279
+ sendInstallIfFirstLaunch()
274
280
 
275
281
  call.resolve()
276
282
  }
277
283
 
284
+ /// Send `app_install` on the first launch of a fresh install. Marks the
285
+ /// install as handled for someone who had the app before Apex, so the
286
+ /// update that adds Apex reports no one as new.
287
+ private func sendInstallIfFirstLaunch() {
288
+ guard autoTrackInstall, consentGranted, let queue = offlineQueue else { return }
289
+ let defaults = UserDefaults.standard
290
+ installLock.lock()
291
+ let decision = FirstLaunchInstall.decide(
292
+ alreadySent: defaults.bool(forKey: FirstLaunchInstall.defaultsKey),
293
+ installedAt: FirstLaunchInstall.installedAt(),
294
+ versionInstalledAt: FirstLaunchInstall.versionInstalledAt(),
295
+ now: Date()
296
+ )
297
+ if decision != .alreadySent { defaults.set(true, forKey: FirstLaunchInstall.defaultsKey) }
298
+ installLock.unlock()
299
+ if debug { print("[apex-capacitor] first-launch install: \(decision)") }
300
+ guard decision == .send else { return }
301
+
302
+ var payload: [String: AnyCodable] = [:]
303
+ payload["type"] = AnyCodable("app_install")
304
+ payload["data"] = AnyCodable(["source": "apex_first_launch"])
305
+ if testMode { payload["testMode"] = AnyCodable(true) }
306
+ payload["platform"] = AnyCodable("ios")
307
+ payload["timestamp"] = AnyCodable(ISO8601DateFormatter().string(from: Date()))
308
+ payload["visitorId"] = AnyCodable(visitorId)
309
+ var mobileSlot: [String: Any] = [
310
+ "releaseChannel": releaseChannel,
311
+ "releaseChannelSource": releaseChannelSource,
312
+ ]
313
+ stampDevice(&mobileSlot)
314
+ payload["mobile"] = AnyCodable(mobileSlot)
315
+ let event = NativeQueuedEvent(
316
+ id: UUID().uuidString.lowercased(),
317
+ payload: payload,
318
+ attempts: 0,
319
+ enqueuedAt: Date()
320
+ )
321
+ try? queue.enqueue(event)
322
+ kickFlush(reason: "track")
323
+ }
324
+
325
+ /// True the first time an install is claimed; the app's own `app_install` after that is dropped.
326
+ private func claimInstall() -> Bool {
327
+ installLock.lock()
328
+ defer { installLock.unlock() }
329
+ let defaults = UserDefaults.standard
330
+ if defaults.bool(forKey: FirstLaunchInstall.defaultsKey) { return false }
331
+ defaults.set(true, forKey: FirstLaunchInstall.defaultsKey)
332
+ return true
333
+ }
334
+
278
335
  /// Forward a freshly-arrived APNs device token to JS listeners and
279
336
  /// register it with the Apex backend. Shared by the explicit
280
337
  /// `registerForPushNotifications()` path and the silent re-register
@@ -930,10 +987,11 @@ public class ApexCapacitorPlugin: CAPPlugin, CAPBridgedPlugin, UNUserNotificatio
930
987
  payload["platform"] = AnyCodable("ios")
931
988
  payload["timestamp"] = AnyCodable(ISO8601DateFormatter().string(from: Date()))
932
989
  payload["visitorId"] = AnyCodable(visitorId)
933
- let mobileSlot: [String: Any] = [
990
+ var mobileSlot: [String: Any] = [
934
991
  "releaseChannel": releaseChannel,
935
992
  "releaseChannelSource": releaseChannelSource,
936
993
  ]
994
+ stampDevice(&mobileSlot)
937
995
  payload["mobile"] = AnyCodable(mobileSlot)
938
996
  let event = NativeQueuedEvent(
939
997
  id: UUID().uuidString.lowercased(),
@@ -947,6 +1005,17 @@ public class ApexCapacitorPlugin: CAPPlugin, CAPBridgedPlugin, UNUserNotificatio
947
1005
 
948
1006
  // MARK: - Events & Queue
949
1007
 
1008
+ /// The device, the tracking answer, and the IDFA when the person allowed
1009
+ /// it. Read per event: the answer can change in Settings mid-session.
1010
+ private func stampDevice(_ slot: inout [String: Any]) {
1011
+ MobileContext.fill(
1012
+ &slot,
1013
+ device: deviceMeta,
1014
+ att: attManager.currentStatus(),
1015
+ adId: adIds.current()
1016
+ )
1017
+ }
1018
+
950
1019
  @objc public func track(_ call: CAPPluginCall) {
951
1020
  guard let queue = offlineQueue else {
952
1021
  call.reject("Plugin not initialized — call initialize() first")
@@ -958,6 +1027,11 @@ public class ApexCapacitorPlugin: CAPPlugin, CAPBridgedPlugin, UNUserNotificatio
958
1027
  call.resolve()
959
1028
  return
960
1029
  }
1030
+ if call.getString("type") == "app_install" && !claimInstall() {
1031
+ if debug { print("[apex-capacitor] app_install already sent for this install; dropping") }
1032
+ call.resolve()
1033
+ return
1034
+ }
961
1035
 
962
1036
  let id = call.getString("id") ?? UUID().uuidString.lowercased()
963
1037
  let payloadDict = call.options.compactMapValues { $0 }
@@ -1004,6 +1078,7 @@ public class ApexCapacitorPlugin: CAPPlugin, CAPBridgedPlugin, UNUserNotificatio
1004
1078
  }
1005
1079
  mobileSlot["releaseChannel"] = releaseChannel
1006
1080
  mobileSlot["releaseChannelSource"] = releaseChannelSource
1081
+ stampDevice(&mobileSlot)
1007
1082
  codablePayload["mobile"] = AnyCodable(mobileSlot)
1008
1083
  let event = NativeQueuedEvent(
1009
1084
  id: id,
@@ -1066,6 +1141,7 @@ public class ApexCapacitorPlugin: CAPPlugin, CAPBridgedPlugin, UNUserNotificatio
1066
1141
  if granted {
1067
1142
  // Resume: flush anything captured before this point.
1068
1143
  kickFlush(reason: "consent")
1144
+ sendInstallIfFirstLaunch()
1069
1145
  } else {
1070
1146
  // Revoke: drop anything queued but not yet sent.
1071
1147
  try? offlineQueue?.clear()
@@ -0,0 +1,72 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <!--
4
+ What @apex-inc/capacitor-plugin collects, merged by Xcode into the app's
5
+ privacy report. Installs and purchases count as tracking because Apex
6
+ sends them to the ad networks the app connects to measure ads. The IDFA
7
+ is read only after the person allows tracking in the ATT prompt. No
8
+ tracking domains are listed: iOS blocks listed domains
9
+ outright when tracking is denied, and Apex's own endpoint also serves
10
+ measurement that needs no permission.
11
+ -->
12
+ <plist version="1.0">
13
+ <dict>
14
+ <key>NSPrivacyTracking</key>
15
+ <true/>
16
+ <key>NSPrivacyTrackingDomains</key>
17
+ <array/>
18
+ <key>NSPrivacyCollectedDataTypes</key>
19
+ <array>
20
+ <dict>
21
+ <key>NSPrivacyCollectedDataType</key>
22
+ <string>NSPrivacyCollectedDataTypeDeviceID</string>
23
+ <key>NSPrivacyCollectedDataTypeLinked</key>
24
+ <true/>
25
+ <key>NSPrivacyCollectedDataTypeTracking</key>
26
+ <true/>
27
+ <key>NSPrivacyCollectedDataTypePurposes</key>
28
+ <array>
29
+ <string>NSPrivacyCollectedDataTypePurposeThirdPartyAdvertising</string>
30
+ <string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
31
+ </array>
32
+ </dict>
33
+ <dict>
34
+ <key>NSPrivacyCollectedDataType</key>
35
+ <string>NSPrivacyCollectedDataTypeProductInteraction</string>
36
+ <key>NSPrivacyCollectedDataTypeLinked</key>
37
+ <true/>
38
+ <key>NSPrivacyCollectedDataTypeTracking</key>
39
+ <true/>
40
+ <key>NSPrivacyCollectedDataTypePurposes</key>
41
+ <array>
42
+ <string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
43
+ <string>NSPrivacyCollectedDataTypePurposeThirdPartyAdvertising</string>
44
+ </array>
45
+ </dict>
46
+ <dict>
47
+ <key>NSPrivacyCollectedDataType</key>
48
+ <string>NSPrivacyCollectedDataTypePurchaseHistory</string>
49
+ <key>NSPrivacyCollectedDataTypeLinked</key>
50
+ <true/>
51
+ <key>NSPrivacyCollectedDataTypeTracking</key>
52
+ <true/>
53
+ <key>NSPrivacyCollectedDataTypePurposes</key>
54
+ <array>
55
+ <string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
56
+ <string>NSPrivacyCollectedDataTypePurposeThirdPartyAdvertising</string>
57
+ </array>
58
+ </dict>
59
+ </array>
60
+ <key>NSPrivacyAccessedAPITypes</key>
61
+ <array>
62
+ <dict>
63
+ <key>NSPrivacyAccessedAPIType</key>
64
+ <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
65
+ <key>NSPrivacyAccessedAPITypeReasons</key>
66
+ <array>
67
+ <string>CA92.1</string>
68
+ </array>
69
+ </dict>
70
+ </array>
71
+ </dict>
72
+ </plist>
@@ -0,0 +1,66 @@
1
+ //
2
+ // FirstLaunchInstallTests.swift
3
+ //
4
+
5
+ import XCTest
6
+ @testable import ApexCapacitorPlugin
7
+
8
+ final class FirstLaunchInstallTests: XCTestCase {
9
+
10
+ private let now = Date(timeIntervalSince1970: 1_790_000_000)
11
+ private let day: TimeInterval = 24 * 3600
12
+
13
+ func testSendsOnTheFirstLaunchOfAFreshInstall() {
14
+ let installed = now.addingTimeInterval(-60)
15
+ XCTAssertEqual(
16
+ FirstLaunchInstall.decide(alreadySent: false, installedAt: installed, versionInstalledAt: installed, now: now),
17
+ .send
18
+ )
19
+ }
20
+
21
+ func testSendsOnceOnly() {
22
+ XCTAssertEqual(
23
+ FirstLaunchInstall.decide(alreadySent: true, installedAt: now, versionInstalledAt: now, now: now),
24
+ .alreadySent
25
+ )
26
+ }
27
+
28
+ func testAnUpdateThatAddsApexIsNotAnInstall() {
29
+ XCTAssertEqual(
30
+ FirstLaunchInstall.decide(
31
+ alreadySent: false,
32
+ installedAt: now.addingTimeInterval(-90 * day),
33
+ versionInstalledAt: now.addingTimeInterval(-day),
34
+ now: now
35
+ ),
36
+ .existingUser
37
+ )
38
+ }
39
+
40
+ func testARecentInstallStillCountsAfterAQuickUpdate() {
41
+ XCTAssertEqual(
42
+ FirstLaunchInstall.decide(
43
+ alreadySent: false,
44
+ installedAt: now.addingTimeInterval(-3 * day),
45
+ versionInstalledAt: now.addingTimeInterval(-day),
46
+ now: now
47
+ ),
48
+ .send
49
+ )
50
+ }
51
+
52
+ func testALateFirstOpenOfANeverUpdatedInstallCounts() {
53
+ let installed = now.addingTimeInterval(-20 * day)
54
+ XCTAssertEqual(
55
+ FirstLaunchInstall.decide(alreadySent: false, installedAt: installed, versionInstalledAt: installed, now: now),
56
+ .send
57
+ )
58
+ }
59
+
60
+ func testSendsWhenTheInstallTimeIsUnknown() {
61
+ XCTAssertEqual(
62
+ FirstLaunchInstall.decide(alreadySent: false, installedAt: nil, versionInstalledAt: nil, now: now),
63
+ .send
64
+ )
65
+ }
66
+ }
@@ -0,0 +1,56 @@
1
+ //
2
+ // MobileContextTests.swift
3
+ //
4
+
5
+ import XCTest
6
+ @testable import ApexCapacitorPlugin
7
+
8
+ final class MobileContextTests: XCTestCase {
9
+
10
+ private let device = DeviceMetadata(
11
+ platform: "ios",
12
+ osVersion: "18.1",
13
+ model: "iPhone16,1",
14
+ appVersion: "3.1.0",
15
+ bundleId: "com.skillshot.app",
16
+ timezone: "America/Chicago",
17
+ locale: "en-US"
18
+ )
19
+
20
+ func testStampsTheDeviceAndTheIdfaWhenTrackingIsAllowed() {
21
+ let fields = MobileContext.fields(
22
+ device: device,
23
+ att: .authorized,
24
+ adId: AdvertisingIdResult(id: "6d92078a-8246-4ba4-ae5b-76104861e7dc", fallback: nil)
25
+ )
26
+ XCTAssertEqual(fields["bundleId"] as? String, "com.skillshot.app")
27
+ XCTAssertEqual(fields["deviceModel"] as? String, "iPhone16,1")
28
+ XCTAssertEqual(fields["attStatus"] as? String, "authorized")
29
+ XCTAssertEqual(fields["idfa"] as? String, "6d92078a-8246-4ba4-ae5b-76104861e7dc")
30
+ }
31
+
32
+ func testNeverSendsTheIdfvAsTheAdvertisingId() {
33
+ let fields = MobileContext.fields(
34
+ device: device,
35
+ att: .denied,
36
+ adId: AdvertisingIdResult(id: "idfv-value", fallback: "idfv")
37
+ )
38
+ XCTAssertNil(fields["idfa"])
39
+ XCTAssertNil(fields["idfv"])
40
+ XCTAssertEqual(fields["attStatus"] as? String, "denied")
41
+ }
42
+
43
+ func testKeepsWhatTheAppSet() {
44
+ var slot: [String: Any] = ["releaseChannel": "app-store", "locale": "fr-FR"]
45
+ MobileContext.fill(
46
+ &slot,
47
+ device: device,
48
+ att: .notDetermined,
49
+ adId: AdvertisingIdResult(id: nil, fallback: nil)
50
+ )
51
+ XCTAssertEqual(slot["locale"] as? String, "fr-FR")
52
+ XCTAssertEqual(slot["releaseChannel"] as? String, "app-store")
53
+ XCTAssertEqual(slot["appVersion"] as? String, "3.1.0")
54
+ XCTAssertEqual(slot["attStatus"] as? String, "not-determined")
55
+ }
56
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apex-inc/capacitor-plugin",
3
- "version": "2.5.1",
3
+ "version": "2.6.0",
4
4
  "description": "Apex Capacitor plugin — iOS/Android attribution, events, deep linking, SKAN, and offline-tolerant tracking for Capacitor apps.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/esm/index.js",