appsflyer-capacitor-plugin 6.15.2 → 6.16.2-rc1

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.
package/README.md CHANGED
@@ -14,8 +14,8 @@
14
14
 
15
15
  ### <a id="plugin-build-for"> This plugin is built for
16
16
 
17
- - Android AppsFlyer SDK **6.15.2**
18
- - iOS AppsFlyer SDK **6.15.3**
17
+ - Android AppsFlyer SDK **6.16.2**
18
+ - iOS AppsFlyer SDK **6.16.2**
19
19
 
20
20
  ## <a id="breaking-changes-6-15-0"> ❗❗ Breaking changes when updating to v6.15.0 ❗❗
21
21
  Starting from v6.15.0, this plugin works only with Capacitor 6. </br>
@@ -64,6 +64,7 @@ const val AF_MANUAL_START = "manualStart"
64
64
  const val AF_IS_SUBJECTED_TO_GDPR = "isUserSubjectToGDPR"
65
65
  const val AF_CONSENT_FOR_DATA_USAGE = "hasConsentForDataUsage"
66
66
  const val AF_CONSENT_FOR_ADS_PERSONALIZATION = "hasConsentForAdsPersonalization"
67
+ const val AF_CONSENT_FOR_ADS_STORAGE = "hasConsentForAdStorage"
67
68
  const val AF_MONETIZATION_NETWORK = "monetizationNetwork"
68
69
  const val AF_CURRENCY_ISO4217_CODE = "currencyIso4217Code"
69
70
  const val AF_REVENUE = "revenue"
@@ -2,6 +2,7 @@ package capacitor.plugin.appsflyer.sdk
2
2
 
3
3
  import android.Manifest
4
4
  import android.content.Intent
5
+ import android.util.Log
5
6
 
6
7
  import com.appsflyer.*
7
8
  import com.appsflyer.attribution.AppsFlyerRequestListener
@@ -34,6 +35,8 @@ class AppsFlyerPlugin : Plugin() {
34
35
  private var conversion: Boolean? = null
35
36
  private var oaoa: Boolean? = null
36
37
  private var udl: Boolean? = null
38
+ @Volatile private var hasSDKStarted: Boolean = false
39
+ @Volatile private var isStarting: Boolean = false
37
40
 
38
41
 
39
42
  override fun handleOnNewIntent(intent: Intent?) {
@@ -278,25 +281,46 @@ class AppsFlyerPlugin : Plugin() {
278
281
  put(AF_IS_STOP, isStopped)
279
282
  }
280
283
  call.resolve(obj)
281
-
282
284
  }
283
285
  }
284
286
 
287
+ @Synchronized
285
288
  @PluginMethod
286
289
  fun startSDK(call: PluginCall) {
287
- AppsFlyerLib.getInstance()
288
- .start(activity ?: context.applicationContext, null, object : AppsFlyerRequestListener {
290
+ when {
291
+ hasSDKStarted -> {
292
+ call.resolve(JSObject().apply {
293
+ put("res", "AppsFlyer SDK already started")
294
+ })
295
+ return
296
+ }
297
+ isStarting -> {
298
+ call.reject("SDK start already in progress. Please wait for the callback.")
299
+ return
300
+ }
301
+ else -> {
302
+ isStarting = true
303
+ }
304
+ }
305
+
306
+ AppsFlyerLib.getInstance().start(
307
+ activity ?: context.applicationContext,
308
+ null,
309
+ object : AppsFlyerRequestListener {
289
310
  override fun onSuccess() {
290
- val result = JSObject().apply {
311
+ hasSDKStarted = true
312
+ isStarting = false
313
+ call.resolve(JSObject().apply {
291
314
  put("res", "success")
292
- }
293
- call.resolve(result)
315
+ })
294
316
  }
295
317
 
296
318
  override fun onError(errCode: Int, msg: String) {
319
+ isStarting = false
297
320
  call.reject("Error Code: $errCode, Message: $msg")
298
321
  }
299
- })
322
+ }
323
+ )
300
324
  }
301
325
 
302
326
  @PluginMethod
@@ -304,6 +328,21 @@ class AppsFlyerPlugin : Plugin() {
304
328
  call.unavailable()
305
329
  }
306
330
 
331
+ @PluginMethod
332
+ fun isSDKStarted(call: PluginCall) {
333
+ val result = JSObject().apply {
334
+ put("isStarted", hasSDKStarted)
335
+ }
336
+ call.resolve(result)
337
+ }
338
+
339
+ @PluginMethod
340
+ fun isSDKStopped(call: PluginCall) {
341
+ val result = JSObject().apply {
342
+ put("isSDKStopped", AppsFlyerLib.getInstance().isStopped)
343
+ }
344
+ call.resolve(result)
345
+ }
307
346
 
308
347
  @PluginMethod(returnType = PluginMethod.RETURN_NONE)
309
348
  fun disableAdvertisingIdentifier(call: PluginCall) {
@@ -371,7 +410,8 @@ class AppsFlyerPlugin : Plugin() {
371
410
  AFHelpers.jsonToStringMap(call.getObject(AF_ADDITIONAL_PARAMETERS))
372
411
  if (currency != null && publicKey != null && signature != null && purchaseData != null) {
373
412
  AppsFlyerLib.getInstance().apply {
374
- registerValidatorListener(context,
413
+ registerValidatorListener(
414
+ context,
375
415
  object : AppsFlyerInAppPurchaseValidatorListener {
376
416
  override fun onValidateInApp() {
377
417
  val ret = JSObject()
@@ -542,13 +582,15 @@ class AppsFlyerPlugin : Plugin() {
542
582
  }
543
583
  }
544
584
 
585
+ @Deprecated("Please use setConsentDataV2 instead, which includes improved handling for GDPR and data privacy.")
545
586
  @PluginMethod(returnType = PluginMethod.RETURN_NONE)
546
587
  fun setConsentData(call: PluginCall) {
547
588
  val consentData = call.getObject("data") ?: return call.reject("Missing consent data")
548
589
 
549
590
  val isUserSubjectToGDPR = consentData.optBoolean(AF_IS_SUBJECTED_TO_GDPR)
550
591
  val hasConsentForDataUsage = consentData.optBoolean(AF_CONSENT_FOR_DATA_USAGE)
551
- val hasConsentForAdsPersonalization = consentData.optBoolean(AF_CONSENT_FOR_ADS_PERSONALIZATION)
592
+ val hasConsentForAdsPersonalization =
593
+ consentData.optBoolean(AF_CONSENT_FOR_ADS_PERSONALIZATION)
552
594
 
553
595
  val consentObject = if (isUserSubjectToGDPR) {
554
596
  AppsFlyerConsent.forGDPRUser(hasConsentForDataUsage, hasConsentForAdsPersonalization)
@@ -561,21 +603,38 @@ class AppsFlyerPlugin : Plugin() {
561
603
  call.resolve()
562
604
  }
563
605
 
606
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
607
+ fun setConsentDataV2(call: PluginCall) {
608
+ AppsFlyerLib.getInstance().setConsentData(
609
+ AppsFlyerConsent(
610
+ isUserSubjectToGDPR = call.getBoolean(AF_IS_SUBJECTED_TO_GDPR),
611
+ hasConsentForDataUsage = call.getBoolean(AF_CONSENT_FOR_DATA_USAGE),
612
+ hasConsentForAdsPersonalization = call.getBoolean(AF_CONSENT_FOR_ADS_PERSONALIZATION),
613
+ hasConsentForAdStorage = call.getBoolean(AF_CONSENT_FOR_ADS_STORAGE)
614
+ )
615
+ )
616
+ }
617
+
564
618
  @PluginMethod(returnType = PluginMethod.RETURN_NONE)
565
619
  fun logAdRevenue(call: PluginCall) {
566
- val adRevenueDataJson = call.data ?: return call.reject("adRevenueData is missing, the data mandatory to use this API.")
620
+ val adRevenueDataJson = call.data
621
+ ?: return call.reject("adRevenueData is missing, the data mandatory to use this API.")
567
622
 
568
623
  // Parse the fields from the adRevenueDataJson object
569
- val monetizationNetwork = adRevenueDataJson.getString(AF_MONETIZATION_NETWORK) ?: return call.reject("monetizationNetwork is missing")
570
- val currencyIso4217Code = adRevenueDataJson.getString(AF_CURRENCY_ISO4217_CODE) ?: return call.reject("currencyIso4217Code is missing")
624
+ val monetizationNetwork = adRevenueDataJson.getString(AF_MONETIZATION_NETWORK)
625
+ ?: return call.reject("monetizationNetwork is missing")
626
+ val currencyIso4217Code = adRevenueDataJson.getString(AF_CURRENCY_ISO4217_CODE)
627
+ ?: return call.reject("currencyIso4217Code is missing")
571
628
  val revenue = adRevenueDataJson.getDouble(AF_REVENUE)
572
629
  if (revenue.isNaN()) {
573
630
  return call.reject("revenue is missing or not a number")
574
631
  }
575
- val additionalParams = AFHelpers.jsonToMap(adRevenueDataJson.getJSObject(AF_ADDITIONAL_PARAMETERS)) // can be nullable
632
+ val additionalParams =
633
+ AFHelpers.jsonToMap(adRevenueDataJson.getJSObject(AF_ADDITIONAL_PARAMETERS)) // can be nullable
576
634
 
577
635
  // Convert the mediationNetwork string to the MediationNetwork enum
578
- val mediationNetworkValue = adRevenueDataJson.getString(AF_MEDIATION_NETWORK) ?: return call.reject("mediationNetwork is missing")
636
+ val mediationNetworkValue = adRevenueDataJson.getString(AF_MEDIATION_NETWORK)
637
+ ?: return call.reject("mediationNetwork is missing")
579
638
  val mediationNetwork: MediationNetwork
580
639
  try {
581
640
  mediationNetwork = MediationNetwork.valueOf(mediationNetworkValue.uppercase())
@@ -179,4 +179,10 @@ export interface AFAdRevenueData {
179
179
  revenue: number;
180
180
  additionalParameters?: StringMap;
181
181
  }
182
+ export interface AFConsentOptions {
183
+ isUserSubjectToGDPR?: boolean | null;
184
+ hasConsentForDataUsage?: boolean | null;
185
+ hasConsentForAdsPersonalization?: boolean | null;
186
+ hasConsentForAdStorage?: boolean | null;
187
+ }
182
188
  export {};
@@ -1,6 +1,6 @@
1
1
  import type { PluginListenerHandle } from "@capacitor/core";
2
2
  import type { AFConstants } from "./Appsflyer_constants";
3
- import type { AFAndroidInAppPurchase, AFAnonymizeUser, AFAppendToDeepLink, AFCuid, AFCurrency, AFData, AFDisable, AFEvent, AFFbDAL, AFFilters, AFHost, AFInit, AFIosInAppPurchase, AFIsStopped, AFLink, AFLinkGenerator, AFOnelinkDomain, AFOnelinkID, AFPath, AFPushPayload, AFRes, AFStop, AFUid, AFUninstall, AFUrls, AFLanguage, OnAppOpenAttribution, OnConversionDataResult, OnDeepLink, AFPromotion, AFEmails, AFLatLng, AFPhone, AFPartnerData, AFLogInvite, AFEnableTCFDataCollection, AFConsentData, AFAdRevenueData } from "./appsflyer_interfaces";
3
+ import type { AFAndroidInAppPurchase, AFAnonymizeUser, AFAppendToDeepLink, AFCuid, AFCurrency, AFData, AFDisable, AFEvent, AFFbDAL, AFFilters, AFHost, AFInit, AFIosInAppPurchase, AFIsStopped, AFLink, AFLinkGenerator, AFOnelinkDomain, AFOnelinkID, AFPath, AFPushPayload, AFRes, AFStop, AFUid, AFUninstall, AFUrls, AFLanguage, OnAppOpenAttribution, OnConversionDataResult, OnDeepLink, AFPromotion, AFEmails, AFLatLng, AFPhone, AFPartnerData, AFLogInvite, AFEnableTCFDataCollection, AFConsentData, AFAdRevenueData, AFConsentOptions } from "./appsflyer_interfaces";
4
4
  export interface AppsFlyerPlugin {
5
5
  addListener(eventName: AFConstants.CONVERSION_CALLBACK, listenerFunc: (event: OnConversionDataResult) => void): PluginListenerHandle;
6
6
  addListener(eventName: AFConstants.OAOA_CALLBACK, listenerFunc: (event: OnAppOpenAttribution) => void): PluginListenerHandle;
@@ -172,6 +172,7 @@ export interface AppsFlyerPlugin {
172
172
  * Use to set user consent data manualy.
173
173
  * if your app doesn't use a CMP compatible with TCF v2.2, use the following method to manualy provide the consent data directly to the SDK.
174
174
  * @param data: AppsFlyerConsent object.
175
+ * @deprecated deprecated since 6.16.2. Use `setConsentDataV2` instead
175
176
  */
176
177
  setConsentData(data: AFConsentData): Promise<void>;
177
178
  /**
@@ -181,4 +182,10 @@ export interface AppsFlyerPlugin {
181
182
  * @param adRevenueData: object used to hold all mandatory parameters of AdRevenue event.
182
183
  */
183
184
  logAdRevenue(data: AFAdRevenueData): Promise<void>;
185
+ /**
186
+ * Use this to set user consent data manualy.
187
+ * if your app doesn't use a CMP compatible with TCF v2.2, use the following method to manualy provide the consent data directly to the SDK.
188
+ * @param options: AFConsentOptions that consists with all the possible options for consent collection, boolean params.
189
+ */
190
+ setConsentDataV2(options: AFConsentOptions): Promise<void>;
184
191
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjD,MAAM,SAAS,GAAG,cAAc,CAAkB,iBAAiB,EAAE,EACpE,CAAC,CAAC;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,SAAS,GAAG,cAAc,CAAkB,iBAAiB,EAAE,EACpE,CAAC,CAAC;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,CAAC"}
@@ -72,7 +72,8 @@ class AppsFlyerConstants {
72
72
  static let AF_MANUAL_START = "manualStart"
73
73
  static let AF_IS_SUBJECTED_TO_DGPR = "isUserSubjectToGDPR"
74
74
  static let AF_CONSENT_FOR_DATA_USAGE = "hasConsentForDataUsage"
75
- static let AF_CONSENT_FOR_ADS_PERSONALIZATION = "hasConsentForAdsPersonalization"
75
+ static let AF_CONSENT_FOR_ADS_PERSONALIZATION = "hasConsentForAdsPersonalization"
76
+ static let AF_CONSENT_FOR_ADS_STORAGE = "hasConsentForAdStorage"
76
77
  static let AF_MONETIZATION_NETWORK = "monetizationNetwork"
77
78
  static let AF_CURRENCY_ISO4217_CODE = "currencyIso4217Code"
78
79
  static let AF_REVENUE = "revenue"
@@ -42,6 +42,7 @@ CAP_PLUGIN(AppsFlyerPlugin, "AppsFlyerPlugin",
42
42
  CAP_PLUGIN_METHOD(setConsentData, CAPPluginReturnNone);
43
43
  CAP_PLUGIN_METHOD(startSDK, CAPPluginReturnPromise);
44
44
  CAP_PLUGIN_METHOD(logAdRevenue, CAPPluginReturnNone);
45
+ CAP_PLUGIN_METHOD(setConsentDataV2, CAPPluginReturnNone);
45
46
 
46
47
 
47
48
 
@@ -5,15 +5,27 @@ import AppsFlyerLib
5
5
 
6
6
  @objc(AppsFlyerPlugin)
7
7
  public class AppsFlyerPlugin: CAPPlugin {
8
- private let APPSFLYER_PLUGIN_VERSION = "6.15.2"
8
+ private let APPSFLYER_PLUGIN_VERSION = "6.16.2-rc1"
9
9
  private var conversion = true
10
10
  private var oaoa = true
11
11
  private var udl = false
12
12
 
13
13
  override public func load() {
14
14
 
15
- NotificationCenter.default.addObserver(self, selector: #selector(self.handleUrlOpened(notification:)), name: Notification.Name.capacitorOpenURL, object: nil)
16
- NotificationCenter.default.addObserver(self, selector: #selector(self.handleUniversalLink(notification:)), name: Notification.Name.capacitorOpenUniversalLink, object: nil)
15
+ NotificationCenter.default
16
+ .addObserver(
17
+ self,
18
+ selector: #selector(self.handleUrlOpened(notification:)),
19
+ name: Notification.Name.capacitorOpenURL,
20
+ object: nil
21
+ )
22
+ NotificationCenter.default
23
+ .addObserver(
24
+ self,
25
+ selector: #selector(self.handleUniversalLink(notification:)),
26
+ name: Notification.Name.capacitorOpenUniversalLink,
27
+ object: nil
28
+ )
17
29
 
18
30
  }
19
31
 
@@ -21,7 +33,12 @@ public class AppsFlyerPlugin: CAPPlugin {
21
33
  @objc func initSDK(_ call: CAPPluginCall){
22
34
  let appsflyer = AppsFlyerLib.shared()
23
35
 
24
- appsflyer.setPluginInfo(plugin: .capacitor, version: APPSFLYER_PLUGIN_VERSION, additionalParams: nil)
36
+ appsflyer
37
+ .setPluginInfo(
38
+ plugin: .capacitor,
39
+ version: APPSFLYER_PLUGIN_VERSION,
40
+ additionalParams: nil
41
+ )
25
42
  guard let devKey = call.getString(AppsFlyerConstants.AF_DEV_KEY) else{
26
43
  call.reject("devkey is missing")
27
44
  return
@@ -34,10 +51,17 @@ public class AppsFlyerPlugin: CAPPlugin {
34
51
 
35
52
  let debug = call.getBool(AppsFlyerConstants.AF_DEBUG, false)
36
53
  let sandbox = call.getBool(AppsFlyerConstants.AF_SANDBOX, false)
37
- let receiptSandbox = call.getBool(AppsFlyerConstants.AF_RECEIPT_SANDBOX, false)
38
- let manualStart = call.getBool(AppsFlyerConstants.AF_MANUAL_START, false)
54
+ let receiptSandbox = call.getBool(
55
+ AppsFlyerConstants.AF_RECEIPT_SANDBOX,
56
+ false
57
+ )
58
+ let manualStart = call.getBool(
59
+ AppsFlyerConstants.AF_MANUAL_START,
60
+ false
61
+ )
39
62
 
40
- conversion = call.getBool(AppsFlyerConstants.AF_CONVERSION_LISTENER, true)
63
+ conversion = call
64
+ .getBool(AppsFlyerConstants.AF_CONVERSION_LISTENER, true)
41
65
  oaoa = call.getBool(AppsFlyerConstants.AF_OAOA, true)
42
66
  udl = call.getBool(AppsFlyerConstants.AF_UDL, false)
43
67
 
@@ -67,20 +91,32 @@ public class AppsFlyerPlugin: CAPPlugin {
67
91
 
68
92
  #if !AFSDK_NO_IDFA
69
93
  if attInterval != nil {
70
- appsflyer.waitForATTUserAuthorization(timeoutInterval: Double(attInterval!))
94
+ appsflyer
95
+ .waitForATTUserAuthorization(
96
+ timeoutInterval: Double(attInterval!)
97
+ )
71
98
  }
72
99
  #endif
73
100
 
74
101
  if !manualStart {
75
102
  startSDK(call)
76
103
  } else {
77
- call.resolve(["res": "SDK initiated successfully. SDK has NOT started yet"])
104
+ call
105
+ .resolve(
106
+ ["res": "SDK initiated successfully. SDK has NOT started yet"]
107
+ )
78
108
  }
79
109
  }
80
110
 
81
111
  @objc func startSDK(_ call: CAPPluginCall) {
82
112
 
83
- NotificationCenter.default.addObserver(self, selector: #selector(sendLaunch), name: UIApplication.didBecomeActiveNotification, object: nil)
113
+ NotificationCenter.default
114
+ .addObserver(
115
+ self,
116
+ selector: #selector(sendLaunch),
117
+ name: UIApplication.didBecomeActiveNotification,
118
+ object: nil
119
+ )
84
120
 
85
121
  AppsFlyerLib.shared().start { dictionary, error in
86
122
  if let error = error {
@@ -98,14 +134,19 @@ public class AppsFlyerPlugin: CAPPlugin {
98
134
  }
99
135
  let eventValue = call.getObject(AppsFlyerConstants.AF_EVENT_VALUE)
100
136
 
101
- AppsFlyerLib.shared().logEvent(name: eventName, values: eventValue) { (response: [String : Any]?, error: Error?) in
102
- if let response = response {
103
- call.resolve(["res":response])
104
- }
105
- if let error = error {
106
- call.reject(error.localizedDescription, nil, error)
137
+ AppsFlyerLib
138
+ .shared()
139
+ .logEvent(name: eventName, values: eventValue) { (
140
+ response: [String : Any]?,
141
+ error: Error?
142
+ ) in
143
+ if let response = response {
144
+ call.resolve(["res":response])
145
+ }
146
+ if let error = error {
147
+ call.reject(error.localizedDescription, nil, error)
148
+ }
107
149
  }
108
- }
109
150
  }
110
151
 
111
152
  @objc func setCustomerUserId(_ call: CAPPluginCall) {
@@ -120,7 +161,10 @@ public class AppsFlyerPlugin: CAPPlugin {
120
161
  @objc func logAdRevenue(_ call: CAPPluginCall) {
121
162
  let adRevenueData = call.jsObjectRepresentation
122
163
  if adRevenueData.isEmpty {
123
- call.reject("adRevenueData is missing, the data mandatory to use this API.")
164
+ call
165
+ .reject(
166
+ "adRevenueData is missing, the data mandatory to use this API."
167
+ )
124
168
  return
125
169
  }
126
170
 
@@ -159,7 +203,12 @@ public class AppsFlyerPlugin: CAPPlugin {
159
203
  )
160
204
 
161
205
  // Log the ad revenue to the AppsFlyer SDK
162
- AppsFlyerLib.shared().logAdRevenue(myAdRevenueData, additionalParameters: additionalParams)
206
+ AppsFlyerLib
207
+ .shared()
208
+ .logAdRevenue(
209
+ myAdRevenueData,
210
+ additionalParameters: additionalParams
211
+ )
163
212
 
164
213
  call.resolve()
165
214
  }
@@ -257,7 +306,12 @@ public class AppsFlyerPlugin: CAPPlugin {
257
306
  for (k,v) in parameters{
258
307
  params[k] = (v as! String)
259
308
  }
260
- AppsFlyerLib.shared().appendParametersToDeeplinkURL(contains: contains, parameters:params )
309
+ AppsFlyerLib
310
+ .shared()
311
+ .appendParametersToDeeplinkURL(
312
+ contains: contains,
313
+ parameters:params
314
+ )
261
315
 
262
316
  }
263
317
 
@@ -337,7 +391,9 @@ public class AppsFlyerPlugin: CAPPlugin {
337
391
  call.reject("Missing boolean value shouldEnableTCFDataCollection")
338
392
  return
339
393
  }
340
- AppsFlyerLib.shared().enableTCFDataCollection(shouldEnableTCFDataCollection)
394
+ AppsFlyerLib
395
+ .shared()
396
+ .enableTCFDataCollection(shouldEnableTCFDataCollection)
341
397
  }
342
398
 
343
399
  @objc func setConsentData(_ call: CAPPluginCall) {
@@ -352,7 +408,10 @@ public class AppsFlyerPlugin: CAPPlugin {
352
408
 
353
409
  let consentObject: AppsFlyerConsent
354
410
  if isUserSubjectToGDPR {
355
- consentObject = AppsFlyerConsent(forGDPRUserWithHasConsentForDataUsage: hasConsentForDataUsage, hasConsentForAdsPersonalization: hasConsentForAdsPersonalization)
411
+ consentObject = AppsFlyerConsent(
412
+ forGDPRUserWithHasConsentForDataUsage: hasConsentForDataUsage,
413
+ hasConsentForAdsPersonalization: hasConsentForAdsPersonalization
414
+ )
356
415
  } else {
357
416
  consentObject = AppsFlyerConsent(nonGDPRUser: ())
358
417
  }
@@ -361,6 +420,30 @@ public class AppsFlyerPlugin: CAPPlugin {
361
420
 
362
421
  call.resolve()
363
422
  }
423
+
424
+ @objc func setConsentDataV2(_ call: CAPPluginCall) {
425
+ // inner helper: convert Bool? to NSNumber?
426
+ func toNSNumber(_ value: Bool?) -> NSNumber? {
427
+ guard let value = value else { return nil }
428
+ return NSNumber(value: value)
429
+ }
430
+
431
+ let isUserSubjectToGDPR = toNSNumber(call.getBool(AppsFlyerConstants.AF_IS_SUBJECTED_TO_DGPR))
432
+ let hasConsentForDataUsage = toNSNumber(call.getBool(AppsFlyerConstants.AF_CONSENT_FOR_DATA_USAGE))
433
+ let hasConsentForAdsPersonalization = toNSNumber(call.getBool(AppsFlyerConstants.AF_CONSENT_FOR_ADS_PERSONALIZATION))
434
+ let hasConsentForAdStorage = toNSNumber(call.getBool(AppsFlyerConstants.AF_CONSENT_FOR_ADS_STORAGE))
435
+
436
+ // Build consent options object and pass to AppsFlyer SDK
437
+ let consentOptions = AppsFlyerConsent(
438
+ isUserSubjectToGDPR: isUserSubjectToGDPR,
439
+ hasConsentForDataUsage: hasConsentForDataUsage,
440
+ hasConsentForAdsPersonalization: hasConsentForAdsPersonalization,
441
+ hasConsentForAdStorage: hasConsentForAdStorage
442
+ )
443
+
444
+ AppsFlyerLib.shared().setConsentData(consentOptions)
445
+ call.resolve()
446
+ }
364
447
 
365
448
  @objc func anonymizeUser(_ call: CAPPluginCall){
366
449
  guard let anonymize = call.getBool(AppsFlyerConstants.AF_ANONYMIZE_USER) else{
@@ -376,7 +459,10 @@ public class AppsFlyerPlugin: CAPPlugin {
376
459
  if stop != nil {
377
460
  AppsFlyerLib.shared().isStopped = stop!
378
461
  }
379
- call.resolve([AppsFlyerConstants.AF_IS_STOP : AppsFlyerLib.shared().isStopped ])
462
+ call
463
+ .resolve(
464
+ [AppsFlyerConstants.AF_IS_STOP : AppsFlyerLib.shared().isStopped ]
465
+ )
380
466
  }
381
467
 
382
468
  @objc func disableSKAdNetwork(_ call: CAPPluginCall){
@@ -418,40 +504,55 @@ public class AppsFlyerPlugin: CAPPlugin {
418
504
  }
419
505
 
420
506
  @objc func generateInviteLink(_ call: CAPPluginCall){
421
- AppsFlyerShareInviteHelper.generateInviteUrl(linkGenerator:
422
- {(_ generator: AppsFlyerLinkGenerator) -> AppsFlyerLinkGenerator in
423
- if let channel = call.getString(AppsFlyerConstants.AF_CHANNEL){
424
- generator.setChannel(channel)
425
- }
426
- if let brandDomain = call.getString(AppsFlyerConstants.AF_BRAND_DOMAIN){
427
- generator.brandDomain = brandDomain
428
- }
429
- if let campaign = call.getString(AppsFlyerConstants.AF_CAMPAIGN){
430
- generator.setCampaign(campaign)
431
- }
432
- if let referrerName = call.getString(AppsFlyerConstants.AF_REFERRER_NAME){
433
- generator.setReferrerName(referrerName)
434
- }
435
- if let referrerImageURL = call.getString(AppsFlyerConstants.AF_REFERRER_IMAGE_URL){
436
- generator.setReferrerImageURL(referrerImageURL)
437
- }
438
- if let referrerCustomerId = call.getString(AppsFlyerConstants.AF_REFERRER_CUSTOMER_ID){
439
- generator.setReferrerCustomerId(referrerCustomerId)
440
- }
441
- if let baseDeeplink = call.getString(AppsFlyerConstants.AF_BASE_DEEPLINK){
442
- generator.setBaseDeeplink(baseDeeplink)
443
- }
444
- if let addParameters = call.getObject(AppsFlyerConstants.AF_ADD_PARAMETERS){
445
- generator.addParameters(addParameters)
446
- }
507
+ AppsFlyerShareInviteHelper.generateInviteUrl(
508
+ linkGenerator:
509
+ {(
510
+ _ generator: AppsFlyerLinkGenerator
511
+ ) -> AppsFlyerLinkGenerator in
512
+ if let channel = call.getString(AppsFlyerConstants.AF_CHANNEL){
513
+ generator.setChannel(channel)
514
+ }
515
+ if let brandDomain = call.getString(AppsFlyerConstants.AF_BRAND_DOMAIN){
516
+ generator.brandDomain = brandDomain
517
+ }
518
+ if let campaign = call.getString(AppsFlyerConstants.AF_CAMPAIGN){
519
+ generator.setCampaign(campaign)
520
+ }
521
+ if let referrerName = call.getString(
522
+ AppsFlyerConstants.AF_REFERRER_NAME
523
+ ){
524
+ generator.setReferrerName(referrerName)
525
+ }
526
+ if let referrerImageURL = call.getString(
527
+ AppsFlyerConstants.AF_REFERRER_IMAGE_URL
528
+ ){
529
+ generator.setReferrerImageURL(referrerImageURL)
530
+ }
531
+ if let referrerCustomerId = call.getString(
532
+ AppsFlyerConstants.AF_REFERRER_CUSTOMER_ID
533
+ ){
534
+ generator.setReferrerCustomerId(referrerCustomerId)
535
+ }
536
+ if let baseDeeplink = call.getString(
537
+ AppsFlyerConstants.AF_BASE_DEEPLINK
538
+ ){
539
+ generator.setBaseDeeplink(baseDeeplink)
540
+ }
541
+ if let addParameters = call.getObject(
542
+ AppsFlyerConstants.AF_ADD_PARAMETERS
543
+ ){
544
+ generator.addParameters(addParameters)
545
+ }
447
546
 
448
- return generator },completionHandler: {url in
449
- if url != nil{
450
- call.resolve([AppsFlyerConstants.AF_LINK_READY: url!.absoluteString])
451
- }else{
452
- call.reject("Failed to generate a link")
453
- }
454
- }
547
+ return generator
548
+ },
549
+ completionHandler: {url in
550
+ if url != nil{
551
+ call.resolve([AppsFlyerConstants.AF_LINK_READY: url!.absoluteString])
552
+ }else{
553
+ call.reject("Failed to generate a link")
554
+ }
555
+ }
455
556
  )
456
557
 
457
558
  }
@@ -462,7 +563,9 @@ public class AppsFlyerPlugin: CAPPlugin {
462
563
  @objc func validateAndLogInAppPurchaseIos(_ call: CAPPluginCall){
463
564
  let currency = call.getString(AppsFlyerConstants.AF_CURRENCY)
464
565
  let price = call.getString(AppsFlyerConstants.AF_PRICE)
465
- let _inAppPurchase = call.getString(AppsFlyerConstants.AF_IN_APP_PURCHASE)
566
+ let _inAppPurchase = call.getString(
567
+ AppsFlyerConstants.AF_IN_APP_PURCHASE
568
+ )
466
569
  let transactionId = call.getString(AppsFlyerConstants.AF_TRANSACTION_ID)
467
570
  let additionalParameters = call.getObject(AppsFlyerConstants.AF_ADDITIONAL_PARAMETERS) ?? [:]
468
571
 
@@ -484,7 +587,6 @@ public class AppsFlyerPlugin: CAPPlugin {
484
587
  return
485
588
  }
486
589
  call.reject((error)?.localizedDescription ?? "error" , emptyInApp.jsonStringRepresentation)
487
-
488
590
  })
489
591
  }else{
490
592
  call.reject("Missing some fields")
@@ -548,7 +650,12 @@ public class AppsFlyerPlugin: CAPPlugin {
548
650
  call.reject("cannot extract the parameters value")
549
651
  return
550
652
  }
551
- AppsFlyerCrossPromotionHelper.logCrossPromoteImpression(appID, campaign: campaign, parameters: parameters)
653
+ AppsFlyerCrossPromotionHelper
654
+ .logCrossPromoteImpression(
655
+ appID,
656
+ campaign: campaign,
657
+ parameters: parameters
658
+ )
552
659
  call.resolve(["res": "ok"])
553
660
 
554
661
  }
@@ -559,10 +666,14 @@ public class AppsFlyerPlugin: CAPPlugin {
559
666
  return
560
667
  }
561
668
  if let enc = call.getBool(AppsFlyerConstants.AF_ENCODE) , enc == true{
562
- AppsFlyerLib.shared().setUserEmails(emails, with: EmailCryptTypeSHA256)
669
+ AppsFlyerLib
670
+ .shared()
671
+ .setUserEmails(emails, with: EmailCryptTypeSHA256)
563
672
 
564
673
  }else{
565
- AppsFlyerLib.shared().setUserEmails(emails, with: EmailCryptTypeNone)
674
+ AppsFlyerLib
675
+ .shared()
676
+ .setUserEmails(emails, with: EmailCryptTypeNone)
566
677
 
567
678
  }
568
679
  call.resolve(["res": "ok"])
@@ -579,7 +690,9 @@ public class AppsFlyerPlugin: CAPPlugin {
579
690
  return
580
691
  }
581
692
 
582
- AppsFlyerLib.shared().logLocation(longitude: longitude, latitude: latitude)
693
+ AppsFlyerLib
694
+ .shared()
695
+ .logLocation(longitude: longitude, latitude: latitude)
583
696
  call.resolve(["res": "ok"])
584
697
 
585
698
  }
@@ -629,7 +742,8 @@ public class AppsFlyerPlugin: CAPPlugin {
629
742
  extension AppsFlyerPlugin{
630
743
  private func reportBridgeReady(){
631
744
  AppsFlyerAttribution.shared.bridgReady = true
632
- NotificationCenter.default.post(name: Notification.Name.appsflyerBridge, object: nil)
745
+ NotificationCenter.default
746
+ .post(name: Notification.Name.appsflyerBridge, object: nil)
633
747
  }
634
748
 
635
749
  @objc private func sendLaunch(){
@@ -650,7 +764,11 @@ extension AppsFlyerPlugin{
650
764
  return
651
765
  }
652
766
  afLogger(msg: "handleUrlOpened with \((url as! URL).absoluteString)")
653
- AppsFlyerAttribution.shared.handleOpenUrl(open: url as! URL, options: options as! [UIApplication.OpenURLOptionsKey: Any])
767
+ AppsFlyerAttribution.shared
768
+ .handleOpenUrl(
769
+ open: url as! URL,
770
+ options: options as! [UIApplication.OpenURLOptionsKey: Any]
771
+ )
654
772
 
655
773
  }
656
774
 
@@ -664,7 +782,9 @@ extension AppsFlyerPlugin{
664
782
  return
665
783
  }
666
784
  user.webpageURL = (url as! URL)
667
- afLogger(msg: "handleUniversalLink with \(user.webpageURL?.absoluteString ?? "null")")
785
+ afLogger(
786
+ msg: "handleUniversalLink with \(user.webpageURL?.absoluteString ?? "null")"
787
+ )
668
788
  AppsFlyerAttribution.shared.continueUserActivity(userActivity: user)
669
789
 
670
790
  }
@@ -673,22 +793,34 @@ extension AppsFlyerPlugin{
673
793
 
674
794
  extension AppsFlyerPlugin : AppsFlyerLibDelegate {
675
795
  public func onConversionDataSuccess(_ conversionInfo: [AnyHashable : Any]) {
676
- let json : [String: Any] = ["callbackName":"onConversionDataSuccess", "data":conversionInfo]
796
+ let json : [String: Any] = [
797
+ "callbackName":"onConversionDataSuccess",
798
+ "data":conversionInfo
799
+ ]
677
800
  self.notifyListeners(AppsFlyerConstants.CONVERSION_CALLBACK, data: json)
678
801
 
679
802
  }
680
803
 
681
804
  public func onConversionDataFail(_ error: Error) {
682
- let json : [String: Any] = ["callbackName":"onConversionDataFail", "status":error.localizedDescription]
805
+ let json : [String: Any] = [
806
+ "callbackName":"onConversionDataFail",
807
+ "status":error.localizedDescription
808
+ ]
683
809
  self.notifyListeners(AppsFlyerConstants.CONVERSION_CALLBACK, data: json)
684
810
  }
685
811
  public func onAppOpenAttribution(_ attributionData: [AnyHashable : Any]) {
686
- let json : [String: Any] = ["callbackName":"onAppOpenAttribution", "data":attributionData]
812
+ let json : [String: Any] = [
813
+ "callbackName":"onAppOpenAttribution",
814
+ "data":attributionData
815
+ ]
687
816
  self.notifyListeners(AppsFlyerConstants.OAOA_CALLBACK, data: json)
688
817
  }
689
818
 
690
819
  public func onAppOpenAttributionFailure(_ error: Error) {
691
- let json : [String: Any] = ["callbackName":"onAppOpenAttributionFailure", "status":error.localizedDescription]
820
+ let json : [String: Any] = [
821
+ "callbackName":"onAppOpenAttributionFailure",
822
+ "status":error.localizedDescription
823
+ ]
692
824
  self.notifyListeners(AppsFlyerConstants.OAOA_CALLBACK, data: json)
693
825
 
694
826
  }
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "appsflyer-capacitor-plugin",
3
- "version": "6.15.2",
4
- "iosSdkVersion": "6.15.3",
5
- "androidSdkVersion": "6.15.2",
6
- "buildNumber": "110",
3
+ "version": "6.16.2-rc1",
4
+ "iosSdkVersion": "6.16.2",
5
+ "androidSdkVersion": "6.16.2",
6
+ "buildNumber": "111",
7
7
  "description": "AppsFlyer SDK plugin for Capacitor",
8
8
  "main": "dist/plugin.cjs.js",
9
9
  "module": "dist/esm/index.js",
@@ -157,4 +157,11 @@ export interface AFAdRevenueData {
157
157
  currencyIso4217Code: string;
158
158
  revenue: number;
159
159
  additionalParameters?: StringMap;
160
- }
160
+ }
161
+
162
+ export interface AFConsentOptions {
163
+ isUserSubjectToGDPR?: boolean | null;
164
+ hasConsentForDataUsage?: boolean | null;
165
+ hasConsentForAdsPersonalization?: boolean | null;
166
+ hasConsentForAdStorage?: boolean | null;
167
+ }
@@ -39,7 +39,8 @@ import type {
39
39
  AFLogInvite,
40
40
  AFEnableTCFDataCollection,
41
41
  AFConsentData,
42
- AFAdRevenueData
42
+ AFAdRevenueData,
43
+ AFConsentOptions
43
44
 
44
45
  } from "./appsflyer_interfaces";
45
46
 
@@ -266,6 +267,7 @@ export interface AppsFlyerPlugin {
266
267
  * Use to set user consent data manualy.
267
268
  * if your app doesn't use a CMP compatible with TCF v2.2, use the following method to manualy provide the consent data directly to the SDK.
268
269
  * @param data: AppsFlyerConsent object.
270
+ * @deprecated deprecated since 6.16.2. Use `setConsentDataV2` instead
269
271
  */
270
272
  setConsentData(data : AFConsentData): Promise<void>
271
273
 
@@ -276,5 +278,11 @@ export interface AppsFlyerPlugin {
276
278
  * @param adRevenueData: object used to hold all mandatory parameters of AdRevenue event.
277
279
  */
278
280
  logAdRevenue(data: AFAdRevenueData): Promise<void>
279
-
281
+
282
+ /**
283
+ * Use this to set user consent data manualy.
284
+ * if your app doesn't use a CMP compatible with TCF v2.2, use the following method to manualy provide the consent data directly to the SDK.
285
+ * @param options: AFConsentOptions that consists with all the possible options for consent collection, boolean params.
286
+ */
287
+ setConsentDataV2(options: AFConsentOptions): Promise<void>
280
288
  }
package/src/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { registerPlugin } from '@capacitor/core';
2
2
 
3
3
  import type { AppsFlyerPlugin } from './definitions';
4
+
4
5
  const AppsFlyer = registerPlugin<AppsFlyerPlugin>('AppsFlyerPlugin', {
5
6
  });
6
7