From c4d0f3855b3cc9706f7081aa260f154fe386e53d Mon Sep 17 00:00:00 2001 From: Paz Lavi Date: Tue, 12 Sep 2023 14:58:48 +0300 Subject: [PATCH 01/14] add recursive search for package.json --- android/build.gradle | 74 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 5 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index e5481c5..ac71624 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,11 +1,74 @@ -// On top of your file import a JSON parser import groovy.json.JsonSlurper +import java.nio.file.FileVisitResult +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.SimpleFileVisitor +import java.nio.file.attribute.BasicFileAttributes + +String getPackageJsonPath() { + return findProperty("APPSFLYER_PACKAGE_JSON") ?: "$rootDir/../node_modules/appsflyer-capacitor-plugin/package.json" +} + +def findNodeModulesDir(File currentDir) { + def dir = currentDir + while (dir != null) { + def nodeModulesDir = new File(dir, 'node_modules') + if (nodeModulesDir.exists()) { + return nodeModulesDir + } + dir = dir.parentFile + } + return null +} + +def findPackageJsonInDep(String packageName) { + def nodeModulesDir = findNodeModulesDir(project.rootDir) + if (nodeModulesDir == null) { + println "node_modules directory not found in any parent directories." + return null + } + + def json = null + + def walker = new SimpleFileVisitor() { + @Override + FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { + if (file.toAbsolutePath().endsWith("appsflyer-capacitor-plugin/package.json")) { + try { + def content = new JsonSlurper().parseText(file.toFile().text) + if (content.name == packageName) { + println "Found package.json: ${file.toAbsolutePath()}" + json = content + return FileVisitResult.TERMINATE + } + } catch (Exception e) { + println "Error parsing JSON in file: ${file.toAbsolutePath().toString()}\n${e.message}\n\t" + } + } + return FileVisitResult.CONTINUE + } + } + while (json == null && nodeModulesDir != null) { + Files.walkFileTree(nodeModulesDir.toPath(), walker) + // parentFile will give us exact same directory so we have to go 2 level upper + // and find another node_modules + nodeModulesDir = findNodeModulesDir(nodeModulesDir.parentFile.parentFile) + } + return json +} + def getPackageJson() { - // Read and parse package.json file from project root - def dir = "$rootDir/../node_modules/appsflyer-capacitor-plugin/package.json" - def inputFile = new File(dir) - def packageJson = new JsonSlurper().parseText(inputFile.text) + def packageJson + def inputFile = new File(getPackageJsonPath()) + if (inputFile.exists()) { + println "found package.json from ENV variable" + packageJson = new JsonSlurper().parseText(inputFile.text) + } else { + println "could not found package.json from ENV variable" + println "searching for package.json recursively" + packageJson = findPackageJsonInDep("appsflyer-capacitor-plugin") + } return packageJson } // Create an easy to use function @@ -19,6 +82,7 @@ def getSDKVersionFromNpm() { // Return the version, you can get any value this way return getPackageJson()["androidSdkVersion"] } + def getPluginBuildVersionFromNpm() { // Return the version, you can get any value this way return getPackageJson()["buildNumber"] From c10b1654ad644bbbd8c1b7120661b6a0ab131a1a Mon Sep 17 00:00:00 2001 From: Dani Kozachkevich Date: Wed, 21 Feb 2024 16:50:08 +0200 Subject: [PATCH 02/14] Added DMA support --- .../appsflyer/sdk/AppsFlyerConstants.kt | 6 ++ .../plugin/appsflyer/sdk/AppsFlyerPlugin.kt | 67 ++++++++++++++++--- examples/CapacitorReact/package.json | 11 ++- ios/Plugin/AppsFlyerConstants.swift | 8 ++- ios/Plugin/AppsFlyerPlugin.m | 4 ++ ios/Plugin/AppsFlyerPlugin.swift | 55 ++++++++++++--- package.json | 6 +- src/appsflyer_interfaces.ts | 38 ++++++++++- src/definitions.ts | 20 +++++- 9 files changed, 185 insertions(+), 30 deletions(-) diff --git a/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerConstants.kt b/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerConstants.kt index bf54099..fa20f03 100644 --- a/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerConstants.kt +++ b/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerConstants.kt @@ -59,3 +59,9 @@ const val AF_DATA = "data" const val AF_PARTNER_ID = "partnerId" const val AF_DEEP_LINK_TIME_OUT = "deepLinkTimeout" const val AF_EVENT_PARAMETERS = "eventParameters" +const val AF_ENABLE_TCF_DATA_COLLECTION = "shouldEnableTCFDataCollection" +const val AF_MANUAL_START = "manualStart" +const val AF_IS_SUBJECTED_TO_DGPR = "isUserSubjectToGDPR" +const val AF_CONSENT_FOR_DATA_USAGE = "hasConsentForDataUsage" +const val AF_CONSENT_FOR_ADS_PERSONALIZATION = "hasConsentForAdsPersonalization" + diff --git a/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerPlugin.kt b/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerPlugin.kt index 1a317b2..2526e74 100644 --- a/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerPlugin.kt +++ b/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerPlugin.kt @@ -49,6 +49,7 @@ class AppsFlyerPlugin : Plugin() { val devKey = call.getString(AF_DEV_KEY) val debug = call.getBoolean(AF_DEBUG, false) val minTime = call.getInt(AF_MIN_TIME) + val manualStart = call.getBoolean(AF_MANUAL_START, false) conversion = call.getBoolean(AF_CONVERSION_LISTENER, true) oaoa = call.getBoolean(AF_OAOA, true) udl = call.getBoolean(AF_UDL, false) @@ -59,7 +60,7 @@ class AppsFlyerPlugin : Plugin() { PluginInfo( com.appsflyer.internal.platform_extension.Plugin.CAPACITOR, BuildConfig.VERSION_NAME - //, mapOf("build_number" to BuildConfig.VERSION_CODE.toString()) + //, mapOf("build_number" to BuildConfig.VERSION_CODE.toString()) ) ) if (debug == true) { @@ -86,18 +87,16 @@ class AppsFlyerPlugin : Plugin() { subscribeForDeepLink(getDeepLinkListener()) } } - start(activity ?: context.applicationContext, null, object : AppsFlyerRequestListener { - override fun onSuccess() { - val ret = JSObject() - ret.put("res", "ok") - call.resolve(ret) - } - override fun onError(p0: Int, p1: String) { - call.reject(p1, p0.toString()) + if (manualStart == false) { + startSDK(call) + } else { + val result = JSObject().apply { + put("success", true) + put("msg", "SDK initiated successfully. SDK has NOT been started yet") } - - }) + call.resolve(result) + } } } @@ -284,6 +283,24 @@ class AppsFlyerPlugin : Plugin() { } } + @PluginMethod(returnType = PluginMethod.RETURN_NONE) + fun startSDK(call: PluginCall) { + AppsFlyerLib.getInstance() + .start(activity ?: context.applicationContext, null, object : AppsFlyerRequestListener { + override fun onSuccess() { + val result = JSObject().apply { + put("success", true) + put("data", "Launch sent successfully") + } + call.resolve(result) + } + + override fun onError(errCode: Int, msg: String) { + call.reject("Error Code: $errCode, Message: $msg") + } + }) + } + @PluginMethod fun disableSKAdNetwork(call: PluginCall) { call.unavailable() @@ -517,6 +534,34 @@ class AppsFlyerPlugin : Plugin() { } + @PluginMethod(returnType = PluginMethod.RETURN_NONE) + fun enableTCFDataCollection(call: PluginCall) { + val shouldEnable = call.getBoolean(AF_ENABLE_TCF_DATA_COLLECTION) + if (shouldEnable != null) { + AppsFlyerLib.getInstance().enableTCFDataCollection(shouldEnable) + } else { + call.reject("Missing boolean value $AF_ENABLE_TCF_DATA_COLLECTION") + } + } + + @PluginMethod(returnType = PluginMethod.RETURN_NONE) + fun setConsentData(call: PluginCall) { + val isUserSubjectToGDPR = call.getBoolean(AF_IS_SUBJECTED_TO_DGPR) ?: false + val hasConsentForDataUsage = call.getBoolean(AF_CONSENT_FOR_DATA_USAGE) ?: false + val hasConsentForAdsPersonalization = + call.getBoolean(AF_CONSENT_FOR_ADS_PERSONALIZATION) ?: false + + val consentObject = if (isUserSubjectToGDPR) { + AppsFlyerConsent.forGDPRUser(hasConsentForDataUsage, hasConsentForAdsPersonalization) + } else { + AppsFlyerConsent.forNonGDPRUser() + } + + AppsFlyerLib.getInstance().setConsentData(consentObject) + + call.resolve() + } + private fun getDeepLinkListener(): DeepLinkListener { return DeepLinkListener { if (udl == true) { diff --git a/examples/CapacitorReact/package.json b/examples/CapacitorReact/package.json index d163fab..413a653 100644 --- a/examples/CapacitorReact/package.json +++ b/examples/CapacitorReact/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "dependencies": { - "@capacitor/android": "^5.0.0", + "@capacitor/android": "5.7.0", "@capacitor/app": "^5.0.0", "@capacitor/core": "^5.0.0", "@capacitor/haptics": "^5.0.0", @@ -49,10 +49,17 @@ "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", + "sync": "npx cap sync", "installFromNpm": "npm install appsflyer-capacitor-plugin && npx cap sync", "installQA": "npm install appsflyer-capacitor-plugin@QA && npx cap sync", "removePlugin": "npm uninstall appsflyer-capacitor-plugin && npx cap sync", - "installLocal": "npm install ../../ && npx cap sync" + "installLocal": "npm install ../../ && npx cap sync", + "addIos": "npx cap add ios", + "addAndroid": "npx cap add android", + "openIos": "npx cap open ios", + "openAndroid": "npx cap open android", + "runIos": "npx cap run ios", + "runAndroid": "npx cap run android" }, "eslintConfig": { "extends": [ diff --git a/ios/Plugin/AppsFlyerConstants.swift b/ios/Plugin/AppsFlyerConstants.swift index 0f31387..f9b9c6b 100644 --- a/ios/Plugin/AppsFlyerConstants.swift +++ b/ios/Plugin/AppsFlyerConstants.swift @@ -29,7 +29,7 @@ class AppsFlyerConstants { static let AF_ONELINK_ID = "onelinkID" static let AF_ONELINK_DOMAIN = "domains" static let AF_DEEPLINK_URLS = "urls" - static let AF_PATH = "path" + static let AF_PATH = "path" static let AF_UID = "uid" static let AF_ANONYMIZE_USER = "anonymizeUser" static let AF_STOP = "stop" @@ -68,5 +68,9 @@ class AppsFlyerConstants { static let AF_EVENT_PARAMETERS = "eventParameters" static let AF_PARTNER_ID = "partnerId" static let AF_DATA = "data" - + static let AF_ENABLE_TCF_DATA_COLLECTION = "shouldEnableTCFDataCollection" + static let AF_MANUAL_START = "manualStart" + static let AF_IS_SUBJECTED_TO_DGPR = "isUserSubjectToGDPR" + static let AF_CONSENT_FOR_DATA_USAGE = "hasConsentForDataUsage" + static let AF_CONSENT_FOR_ADS_PERSONALIZATION = "hasConsentForAdsPersonalization" } diff --git a/ios/Plugin/AppsFlyerPlugin.m b/ios/Plugin/AppsFlyerPlugin.m index 38bc975..7f6bf60 100644 --- a/ios/Plugin/AppsFlyerPlugin.m +++ b/ios/Plugin/AppsFlyerPlugin.m @@ -38,6 +38,10 @@ CAP_PLUGIN_METHOD(setPartnerData, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(logInvite, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(setSharingFilterForPartners, CAPPluginReturnPromise); + CAP_PLUGIN_METHOD(enableTCFDataCollection, CAPPluginReturnPromise); + CAP_PLUGIN_METHOD(setConsentData, CAPPluginReturnPromise); + CAP_PLUGIN_METHOD(startSDK, CAPPluginReturnPromise); + diff --git a/ios/Plugin/AppsFlyerPlugin.swift b/ios/Plugin/AppsFlyerPlugin.swift index 8207035..e81cd17 100644 --- a/ios/Plugin/AppsFlyerPlugin.swift +++ b/ios/Plugin/AppsFlyerPlugin.swift @@ -34,7 +34,8 @@ public class AppsFlyerPlugin: CAPPlugin { let debug = call.getBool(AppsFlyerConstants.AF_DEBUG, false) let sandbox = call.getBool(AppsFlyerConstants.AF_SANDBOX, false) - let receiptSandbox = call.getBool(AppsFlyerConstants.AF_RECEIPT_SANDBOX , false) + let receiptSandbox = call.getBool(AppsFlyerConstants.AF_RECEIPT_SANDBOX, false) + let manualStart = call.getBool(AppsFlyerConstants.AF_MANUAL_START, false) conversion = call.getBool(AppsFlyerConstants.AF_CONVERSION_LISTENER, true) oaoa = call.getBool(AppsFlyerConstants.AF_OAOA, true) @@ -69,18 +70,29 @@ public class AppsFlyerPlugin: CAPPlugin { appsflyer.waitForATTUserAuthorization(timeoutInterval: Double(attInterval!)) } #endif - + + if !manualStart { + startSDK() + } else { + let result = [ + "success": true, + "msg": "SDK initiated successfully. SDK has NOT been started yet" + ] as [String: Any] + + call.resolve(result) + } + } + + @obj func startSDK(_ call: CAPPluginCall) { + NotificationCenter.default.addObserver(self, selector: #selector(sendLaunch), name: UIApplication.didBecomeActiveNotification, object: nil) - appsflyer.start(completionHandler: { (dictionnary, error) in - if (error != nil){ - call.reject(error!.localizedDescription) - return + AppsFlyerLib.shared().start { dictionary, error in + if let error = error { + call.reject(error.localizedDescription) } else { - call.resolve(["res":"ok"]) - return + call.resolve(["res": "ok"]) } - }) } @objc func logEvent(_ call: CAPPluginCall){ @@ -240,6 +252,31 @@ public class AppsFlyerPlugin: CAPPlugin { @objc func setDisableNetworkData(_ call: CAPPluginCall){ call.unavailable("Android only method - has no effact on iOS apps") } + + @objc func enableTCFDataCollection(_ call: CAPPluginCall){ + guard let shouldEnableTCFDataCollection = call.getBool(AppsFlyerConstants.AF_ENABLE_TCF_DATA_COLLECTION) else { + call.reject("Missing boolean value shouldEnableTCFDataCollection") + return + } + AppsFlyerLib.shared().enableTCFDataCollection = shouldEnableTCFDataCollection + } + + @objc func setConsentData(_ call: CAPPluginCall) { + let isUserSubjectToGDPR = call.getBool(AppsFlyerConstants.AF_IS_SUBJECTED_TO_DGPR) ?? false + let hasConsentForDataUsage = call.getBool(AppsFlyerConstants.AF_CONSENT_FOR_DATA_USAGE) ?? false + let hasConsentForAdsPersonalization = call.getBool(AppsFlyerConstants.AF_CONSENT_FOR_ADS_PERSONALIZATION) ?? false + + let consentObject: AppsFlyerConsent + if isUserSubjectToGDPR { + consentObject = AppsFlyerConsent.forGDPRUser(hasConsent: hasConsentForDataUsage, andAdsPersonalization: hasConsentForAdsPersonalization) + } else { + consentObject = AppsFlyerConsent.forNonGDPRUser() + } + + AppsFlyerLib.shared().setConsentData(consentObject) + + call.resolve() + } @objc func anonymizeUser(_ call: CAPPluginCall){ guard let anonymize = call.getBool(AppsFlyerConstants.AF_ANONYMIZE_USER) else{ diff --git a/package.json b/package.json index 4084cf5..527091e 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "appsflyer-capacitor-plugin", - "version": "6.12.1", - "iosSdkVersion": "6.12.1", - "androidSdkVersion": "6.12.1", + "version": "6.13.0", + "iosSdkVersion": "6.13.0", + "androidSdkVersion": "6.13.0", "buildNumber": "10", "description": "AppsFlyer SDK plugin for Capacitor", "main": "dist/plugin.cjs.js", diff --git a/src/appsflyer_interfaces.ts b/src/appsflyer_interfaces.ts index 895fb85..a26ca48 100644 --- a/src/appsflyer_interfaces.ts +++ b/src/appsflyer_interfaces.ts @@ -10,7 +10,7 @@ export interface AFInit{ useReceiptValidationSandbox?: boolean; minTimeBetweenSessions?: number deepLinkTimeout?: number - + manualStart?: boolean; } export interface AFEvent{ @@ -112,3 +112,39 @@ export interface AFAppendToDeepLink{contains: string; parameters: StringMap; } +export interface AFEnableTCFDataCollection { shouldEnableTCFDataCollection: boolean } + +export interface AppsFlyerConsent { + isUserSubjectToGDPR: boolean, + hasConsentForDataUsage?: boolean, + hasConsentForAdsPersonalization?: boolean +} + +class AppsFlyerConsentClass { + public isUserSubjectToGDPR: boolean; + public hasConsentForDataUsage?: boolean; + public hasConsentForAdsPersonalization?: boolean; + + private constructor(isUserSubjectToGDPR: boolean, hasConsentForDataUsage?: boolean, hasConsentForAdsPersonalization?: boolean) { + this.isUserSubjectToGDPR = isUserSubjectToGDPR; + this.hasConsentForDataUsage = hasConsentForDataUsage; + this.hasConsentForAdsPersonalization = hasConsentForAdsPersonalization; + } + + static forGDPRUser(hasConsentForDataUsage: boolean, hasConsentForAdsPersonalization: boolean): AppsFlyerConsent { + return new AppsFlyerConsentClass(true, hasConsentForDataUsage, hasConsentForAdsPersonalization); + } + + static forNonGDPRUser(): AppsFlyerConsent { + return new AppsFlyerConsentClass(false); + } +} + +export const AppsFlyerConsent = { + forGDPRUser: AppsFlyerConsentClass.forGDPRUser, + forNonGDPRUser: AppsFlyerConsentClass.forNonGDPRUser +}; + +export interface AFConsentData { + data: AppsFlyerConsent +} diff --git a/src/definitions.ts b/src/definitions.ts index af622be..7f190f5 100644 --- a/src/definitions.ts +++ b/src/definitions.ts @@ -36,7 +36,9 @@ import type { AFLatLng, AFPhone, AFPartnerData, - AFLogInvite + AFLogInvite, + AFEnableTCFDataCollection, + AFConsentData } from "./appsflyer_interfaces"; export interface AppsFlyerPlugin { @@ -245,6 +247,20 @@ export interface AppsFlyerPlugin { * * @param disable Defaults to false */ - setDisableNetworkData(disable : AFDisable): Promise; + setDisableNetmanualStartworkData(disable : AFDisable): Promise; + + /** + * Use to opt-in/out the automatic collection of consent data, for users who use a CMP. + * Flag value will be persisted between app sessions. + */ + enableTCFDataCollection(shouldEnableTCFDataCollection: AFEnableTCFDataCollection): Promise + + /** + * Use to set user consent data manualy. + * 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. + * @param data: AppsFlyerConsent object. + */ + setConsentData(data : AFConsentData): Promise + } From 74eb9e10aef3bf554fb96da2c409bad02b7aacec Mon Sep 17 00:00:00 2001 From: Dani Kozachkevich Date: Thu, 22 Feb 2024 15:51:46 +0200 Subject: [PATCH 03/14] Added startSDK api --- ios/Plugin/AppsFlyerPlugin.swift | 2 +- src/definitions.ts | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ios/Plugin/AppsFlyerPlugin.swift b/ios/Plugin/AppsFlyerPlugin.swift index e81cd17..32b7b53 100644 --- a/ios/Plugin/AppsFlyerPlugin.swift +++ b/ios/Plugin/AppsFlyerPlugin.swift @@ -72,7 +72,7 @@ public class AppsFlyerPlugin: CAPPlugin { #endif if !manualStart { - startSDK() + startSDK(call) } else { let result = [ "success": true, diff --git a/src/definitions.ts b/src/definitions.ts index 7f190f5..dc566fe 100644 --- a/src/definitions.ts +++ b/src/definitions.ts @@ -39,6 +39,7 @@ import type { AFLogInvite, AFEnableTCFDataCollection, AFConsentData + } from "./appsflyer_interfaces"; export interface AppsFlyerPlugin { @@ -65,6 +66,12 @@ export interface AppsFlyerPlugin { */ initSDK(options: AFInit): Promise; + /** + * Use this method to start AppsFlyer SDK, only on manual init mode. + * This API should be called as soon as. + */ + startSDK(): Promise; + /** * Log an in-app event. * From de8e199ebb5b746f83cc39fe6c01834f2498841f Mon Sep 17 00:00:00 2001 From: Dani Kozachkevich Date: Sun, 25 Feb 2024 14:09:26 +0200 Subject: [PATCH 04/14] Fixed plugin method annotation, typo fix, podfile update --- .../capacitor/plugin/appsflyer/sdk/AppsFlyerPlugin.kt | 2 +- ios/Plugin/AppsFlyerPlugin.swift | 11 ++++++----- ios/Podfile | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerPlugin.kt b/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerPlugin.kt index 2526e74..5479438 100644 --- a/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerPlugin.kt +++ b/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerPlugin.kt @@ -283,7 +283,7 @@ class AppsFlyerPlugin : Plugin() { } } - @PluginMethod(returnType = PluginMethod.RETURN_NONE) + @PluginMethod fun startSDK(call: PluginCall) { AppsFlyerLib.getInstance() .start(activity ?: context.applicationContext, null, object : AppsFlyerRequestListener { diff --git a/ios/Plugin/AppsFlyerPlugin.swift b/ios/Plugin/AppsFlyerPlugin.swift index 32b7b53..bcdfe52 100644 --- a/ios/Plugin/AppsFlyerPlugin.swift +++ b/ios/Plugin/AppsFlyerPlugin.swift @@ -83,8 +83,8 @@ public class AppsFlyerPlugin: CAPPlugin { } } - @obj func startSDK(_ call: CAPPluginCall) { - + @objc func startSDK(_ call: CAPPluginCall) { + NotificationCenter.default.addObserver(self, selector: #selector(sendLaunch), name: UIApplication.didBecomeActiveNotification, object: nil) AppsFlyerLib.shared().start { dictionary, error in @@ -93,6 +93,7 @@ public class AppsFlyerPlugin: CAPPlugin { } else { call.resolve(["res": "ok"]) } + } } @objc func logEvent(_ call: CAPPluginCall){ @@ -258,7 +259,7 @@ public class AppsFlyerPlugin: CAPPlugin { call.reject("Missing boolean value shouldEnableTCFDataCollection") return } - AppsFlyerLib.shared().enableTCFDataCollection = shouldEnableTCFDataCollection + AppsFlyerLib.shared().enableTCFDataCollection(shouldEnableTCFDataCollection) } @objc func setConsentData(_ call: CAPPluginCall) { @@ -268,9 +269,9 @@ public class AppsFlyerPlugin: CAPPlugin { let consentObject: AppsFlyerConsent if isUserSubjectToGDPR { - consentObject = AppsFlyerConsent.forGDPRUser(hasConsent: hasConsentForDataUsage, andAdsPersonalization: hasConsentForAdsPersonalization) + consentObject = AppsFlyerConsent(forGDPRUserWithHasConsentForDataUsage: hasConsentForDataUsage, hasConsentForAdsPersonalization: hasConsentForAdsPersonalization) } else { - consentObject = AppsFlyerConsent.forNonGDPRUser() + consentObject = AppsFlyerConsent(nonGDPRUser: ()) } AppsFlyerLib.shared().setConsentData(consentObject) diff --git a/ios/Podfile b/ios/Podfile index 78905ba..06f963a 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -10,7 +10,7 @@ end target 'Plugin' do capacitor_pods - pod 'AppsFlyerFramework', ' 6.10.1' + pod 'AppsFlyerFramework', ' 6.13.0' end target 'PluginTests' do From 67aedfb988b9326269458a08796951db8bcf4e46 Mon Sep 17 00:00:00 2001 From: Paz Lavi Date: Sun, 25 Feb 2024 14:16:41 +0200 Subject: [PATCH 05/14] change to buildDir --- android/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/build.gradle b/android/build.gradle index ac71624..d2eddbf 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -7,7 +7,7 @@ import java.nio.file.SimpleFileVisitor import java.nio.file.attribute.BasicFileAttributes String getPackageJsonPath() { - return findProperty("APPSFLYER_PACKAGE_JSON") ?: "$rootDir/../node_modules/appsflyer-capacitor-plugin/package.json" + return findProperty("APPSFLYER_PACKAGE_JSON") ?: "$buildDir/../node_modules/appsflyer-capacitor-plugin/package.json" } def findNodeModulesDir(File currentDir) { From 27c68844d9b8fb509e48d74efe67a297ecf6cd0a Mon Sep 17 00:00:00 2001 From: Dani Kozachkevich Date: Mon, 26 Feb 2024 12:04:19 +0200 Subject: [PATCH 06/14] fixed wrong data object access --- .../plugin/appsflyer/sdk/AppsFlyerConstants.kt | 2 +- .../plugin/appsflyer/sdk/AppsFlyerPlugin.kt | 16 ++++++++++------ ios/Plugin/AppsFlyerPlugin.swift | 13 +++++++++---- src/appsflyer_interfaces.ts | 10 +++++----- src/definitions.ts | 1 - 5 files changed, 25 insertions(+), 17 deletions(-) diff --git a/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerConstants.kt b/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerConstants.kt index fa20f03..a0dbc6f 100644 --- a/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerConstants.kt +++ b/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerConstants.kt @@ -61,7 +61,7 @@ const val AF_DEEP_LINK_TIME_OUT = "deepLinkTimeout" const val AF_EVENT_PARAMETERS = "eventParameters" const val AF_ENABLE_TCF_DATA_COLLECTION = "shouldEnableTCFDataCollection" const val AF_MANUAL_START = "manualStart" -const val AF_IS_SUBJECTED_TO_DGPR = "isUserSubjectToGDPR" +const val AF_IS_SUBJECTED_TO_GDPR = "isUserSubjectToGDPR" const val AF_CONSENT_FOR_DATA_USAGE = "hasConsentForDataUsage" const val AF_CONSENT_FOR_ADS_PERSONALIZATION = "hasConsentForAdsPersonalization" diff --git a/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerPlugin.kt b/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerPlugin.kt index 5479438..3ca0f04 100644 --- a/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerPlugin.kt +++ b/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerPlugin.kt @@ -2,6 +2,7 @@ package capacitor.plugin.appsflyer.sdk import android.Manifest import android.content.Intent +import android.util.Log import com.appsflyer.* import com.appsflyer.attribution.AppsFlyerRequestListener @@ -89,6 +90,7 @@ class AppsFlyerPlugin : Plugin() { } if (manualStart == false) { + Log.d("appsflyer_", "manual start: $manualStart") startSDK(call) } else { val result = JSObject().apply { @@ -289,8 +291,7 @@ class AppsFlyerPlugin : Plugin() { .start(activity ?: context.applicationContext, null, object : AppsFlyerRequestListener { override fun onSuccess() { val result = JSObject().apply { - put("success", true) - put("data", "Launch sent successfully") + put("res", "success") } call.resolve(result) } @@ -546,10 +547,13 @@ class AppsFlyerPlugin : Plugin() { @PluginMethod(returnType = PluginMethod.RETURN_NONE) fun setConsentData(call: PluginCall) { - val isUserSubjectToGDPR = call.getBoolean(AF_IS_SUBJECTED_TO_DGPR) ?: false - val hasConsentForDataUsage = call.getBoolean(AF_CONSENT_FOR_DATA_USAGE) ?: false - val hasConsentForAdsPersonalization = - call.getBoolean(AF_CONSENT_FOR_ADS_PERSONALIZATION) ?: false + val consentData = call.getObject("data") ?: return with (call) { + reject("Missing consent data") + } + + val isUserSubjectToGDPR = consentData.optBoolean(AF_IS_SUBJECTED_TO_GDPR) + val hasConsentForDataUsage = consentData.optBoolean(AF_CONSENT_FOR_DATA_USAGE) + val hasConsentForAdsPersonalization = consentData.optBoolean(AF_CONSENT_FOR_ADS_PERSONALIZATION) val consentObject = if (isUserSubjectToGDPR) { AppsFlyerConsent.forGDPRUser(hasConsentForDataUsage, hasConsentForAdsPersonalization) diff --git a/ios/Plugin/AppsFlyerPlugin.swift b/ios/Plugin/AppsFlyerPlugin.swift index bcdfe52..bb85a44 100644 --- a/ios/Plugin/AppsFlyerPlugin.swift +++ b/ios/Plugin/AppsFlyerPlugin.swift @@ -91,7 +91,7 @@ public class AppsFlyerPlugin: CAPPlugin { if let error = error { call.reject(error.localizedDescription) } else { - call.resolve(["res": "ok"]) + call.resolve(["res": "success"]) } } } @@ -263,9 +263,14 @@ public class AppsFlyerPlugin: CAPPlugin { } @objc func setConsentData(_ call: CAPPluginCall) { - let isUserSubjectToGDPR = call.getBool(AppsFlyerConstants.AF_IS_SUBJECTED_TO_DGPR) ?? false - let hasConsentForDataUsage = call.getBool(AppsFlyerConstants.AF_CONSENT_FOR_DATA_USAGE) ?? false - let hasConsentForAdsPersonalization = call.getBool(AppsFlyerConstants.AF_CONSENT_FOR_ADS_PERSONALIZATION) ?? false + guard let consentData = call.getObject("data") else { + call.reject("Consent data is missing") + return + } + + let isUserSubjectToGDPR = consentData[AppsFlyerConstants.AF_IS_SUBJECTED_TO_DGPR] as? Bool ?? false + let hasConsentForDataUsage = consentData[AppsFlyerConstants.AF_CONSENT_FOR_DATA_USAGE] as? Bool ?? false + let hasConsentForAdsPersonalization = consentData[AppsFlyerConstants.AF_CONSENT_FOR_ADS_PERSONALIZATION] as? Bool ?? false let consentObject: AppsFlyerConsent if isUserSubjectToGDPR { diff --git a/src/appsflyer_interfaces.ts b/src/appsflyer_interfaces.ts index a26ca48..49284b8 100644 --- a/src/appsflyer_interfaces.ts +++ b/src/appsflyer_interfaces.ts @@ -114,13 +114,13 @@ export interface AFAppendToDeepLink{contains: string; export interface AFEnableTCFDataCollection { shouldEnableTCFDataCollection: boolean } -export interface AppsFlyerConsent { +export interface IAppsFlyerConsent { isUserSubjectToGDPR: boolean, hasConsentForDataUsage?: boolean, hasConsentForAdsPersonalization?: boolean } -class AppsFlyerConsentClass { +class AppsFlyerConsentClass implements IAppsFlyerConsent { public isUserSubjectToGDPR: boolean; public hasConsentForDataUsage?: boolean; public hasConsentForAdsPersonalization?: boolean; @@ -131,11 +131,11 @@ class AppsFlyerConsentClass { this.hasConsentForAdsPersonalization = hasConsentForAdsPersonalization; } - static forGDPRUser(hasConsentForDataUsage: boolean, hasConsentForAdsPersonalization: boolean): AppsFlyerConsent { + static forGDPRUser(hasConsentForDataUsage: boolean, hasConsentForAdsPersonalization: boolean): IAppsFlyerConsent { return new AppsFlyerConsentClass(true, hasConsentForDataUsage, hasConsentForAdsPersonalization); } - static forNonGDPRUser(): AppsFlyerConsent { + static forNonGDPRUser(): IAppsFlyerConsent { return new AppsFlyerConsentClass(false); } } @@ -146,5 +146,5 @@ export const AppsFlyerConsent = { }; export interface AFConsentData { - data: AppsFlyerConsent + data: IAppsFlyerConsent } diff --git a/src/definitions.ts b/src/definitions.ts index dc566fe..1ca0aed 100644 --- a/src/definitions.ts +++ b/src/definitions.ts @@ -68,7 +68,6 @@ export interface AppsFlyerPlugin { /** * Use this method to start AppsFlyer SDK, only on manual init mode. - * This API should be called as soon as. */ startSDK(): Promise; From b6a1c074c00bea9d4095ff791c43283cb659a9f3 Mon Sep 17 00:00:00 2001 From: Dani Kozachkevich Date: Mon, 26 Feb 2024 18:39:08 +0200 Subject: [PATCH 07/14] Updated README, changed back capacitor android dependencie --- README.md | 13 ++-- docs/API.md | 91 +++++++++++++++++++++++ docs/DMA.md | 105 +++++++++++++++++++++++++++ examples/CapacitorReact/package.json | 2 +- src/definitions.ts | 2 +- 5 files changed, 205 insertions(+), 8 deletions(-) create mode 100644 docs/DMA.md diff --git a/README.md b/README.md index a28ccc7..d929cc7 100644 --- a/README.md +++ b/README.md @@ -14,16 +14,16 @@ ### This plugin is built for -- Android AppsFlyer SDK **6.12.1** -- iOS AppsFlyer SDK **6.12.1** +- Android AppsFlyer SDK **6.13.0** +- iOS AppsFlyer SDK **6.13.0** -## ❗❗ Breaking changes when updating to v6.12.1❗❗ +## ❗❗ Breaking changes when updating to v6.12.1 ❗❗ Starting from v6.12.1, this plugin works only with Capacitor 5.
If you are still interested in using Capacitor 4, please follow the instructions [here](/docs/Installation.md#cap4) to install the latest version that supports Capacitor 4. -##
❗❗ Breaking changes when updating to v6.9.2❗❗ +## ❗❗ Breaking changes when updating to v6.9.2 ❗❗ Starting from v6.9.2, this plugin works only with Capacitor 4.
If you are still interested in using Capacitor 3, please follow the instructions [here](/docs/Installation.md#cap3) to install the latest version that supports Capacitor 3. @@ -37,9 +37,10 @@ If you are still interested in using Capacitor 3, please follow the instructions ## 📖 Guides - [Adding the SDK to your project](/docs/Installation.md) -- [Initializing the SDK](/docs/BasicIntegration.md) +- [Initializing The SDK](/docs/BasicIntegration.md) - [In-app Events](/docs/InAppEvents.md) - [Deep Linking](/docs/DeepLink.md) - [Advanced API](/docs/AdvancedAPI.md) -- [Testing the integration](/docs/Testing.md) +- [Testing The integration](/docs/Testing.md) - [API](/docs/API.md) +- [Set Consent For DMA Compliance](/docs/DMA.md) diff --git a/docs/API.md b/docs/API.md index 4887d63..70c71cc 100644 --- a/docs/API.md +++ b/docs/API.md @@ -56,6 +56,10 @@ The list of available methods for this plugin is described below. * [`setSharingFilterForPartners`](#setsharingfilterforpartners) * [`setSharingFilter`](#setsharingfilter) - Deprecated * [`setSharingFilterForAllPartners`](#setsharingfilterforallpartners) - Deprecated +* [`startSDK`](#startSDK) - New +* [`enableTCFDataCollection`](#enableTCFDataCollection) - New +* [`setConsentData`](#setConsentData) - New + @@ -908,6 +912,73 @@ Use to log a user-invite in-app event (af_invite). .catch(e => console.log(e)); ``` +-------------------- + +### startSDK +```typescript +startSDK(): Promise; +``` + +Use this method to start AppsFlyer SDK, available only on manual start mode. + +**Returns:** Promise<
AFRes> + +**Usage Example:** +```typescript + AppsFlyer.startSDK() + .then(res => console.log("AppsFlyer SDK Start Response: ", res.res)) + .catch(err => console.error("AppsFlyer SDK Start Error: ", err)); +``` + +-------------------- + +### enableTCFDataCollection +```typescript +enableTCFDataCollection(shouldEnableTCFDataCollection: AFEnableTCFDataCollection): Promise +``` + +Use to opt-in/out the automatic collection of consent data, for users who use a CMP. +Flag value will be persisted between app sessions. + +| Param | Type | +| ------------- | ------------------------------------------------------- | +| **`shouldEnableTCFDataCollection`** | AFEnableTCFDataCollection | + +**Returns:** Promise + +**Usage Example:** +```typescript + AppsFlyer.enableTCFDataCollection({shouldEnableTCFDataCollection : }) +``` + +-------------------- + +### setConsentData +```typescript +setConsentData(data : AFConsentData): Promise +``` + +Use to set user consent data manualy. +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. + +| Param | Type | +| ------------- | ------------------------------------------------------- | +| **`data`** | AFConsentData | + +**Returns:** Promise + +**Usage Example:** +If *GDPR doesn’t* to the user, perform the following: +```typescript + AppsFlyer.setConsentData({data: AppsFlyerConsent.forNonGDPRUser()}) +``` +If *GDPR applies* apply to the user perform the following: +```typescript + AppsFlyer.setConsentData({data : AppsFlyerConsent.forGDPRUser(, )}); +``` +*Please take a look how to properly setConsentData Manualy in [Set Consent For DMA Compliance](/docs/DMA.md#)* + + ## Interfaces @@ -1193,6 +1264,26 @@ Use to log a user-invite in-app event (af_invite). | **`eventParameters`** | StringMap | | **`channel`** | string| +#### AFEnableTCFDataCollection + +| Prop | Type | +| ----------------- | ----------------------------------------------- | +| **`shouldEnableTCFDataCollection`** | boolean| + +#### AFConsentData + +| Prop | Type | +| ----------------- | ----------------------------------------------- | +| **`data`** | IAppsFlyerConsent| + +#### IAppsFlyerConsent + +| Prop | Type | +| ----------------- | ----------------------------------------------- | +| **`isUserSubjectToGDPR`** | boolean| +| **`hasConsentForDataUsage`** | boolean| +| **`hasConsentForAdsPersonalization`** | boolean| + ## Enums diff --git a/docs/DMA.md b/docs/DMA.md new file mode 100644 index 0000000..6550629 --- /dev/null +++ b/docs/DMA.md @@ -0,0 +1,105 @@ +# Set Consent For DMA Compliance + +Following the DMA regulations that were set by the European Commission, Google (and potentially other SRNs in the future) require to send them the user’s consent data in order to interact with them during the attribution process. In our latest plugin update (6.13.0), we've introduced two new public APIs, enhancing our support for user consent and data collection preferences in line with evolving digital market regulations. +There are two alternative ways for gathering consent data: + +- Through a Consent Management Platform (CMP): If the app uses a CMP that complies with the Transparency and Consent Framework (TCF) v2.2 protocol, the SDK can automatically retrieve the consent details. +### OR +- Through a dedicated SDK API: Developers can pass Google's required consent data directly to the SDK using a specific API designed for this purpose. + +## Use CMP to collect consent data +A CMP compatible with TCF v2.2 collects DMA consent data and stores it in NSUserDefaults (iOS) and SharedPreferences (Android). To enable the SDK to access this data and include it with every event, follow these steps: +1. Call AppsFlyer.enableTCFDataCollection({shouldEnableTCFDataCollection : true}); +2. Initialize the SDK in manual start mode by simply adding manualStart: true in the AppsFlyer.initSDK() method. +3. Use the CMP to decide if you need the consent dialog in the current session to acquire the consent data. If you need the consent dialog move to step 4, otherwise move to step 5. +4. Get confirmation from the CMP that the user has made their consent decision and the data is available in NSUserDefaults/SharedPreferences. +5. Call AppsFlyer.startSDK() +```typescript + AppsFlyer.initSDK({ + appID: '1234567890', + devKey: 'your_dev_key', + isDebug: true, + registerOnDeepLink: true, + minTimeBetweenSessions: 6, + registerConversionListener: true, + registerOnAppOpenAttribution: false, + useReceiptValidationSandbox: true, + useUninstallSandbox: true, + manualStart: true // <--- Manual Start + }); + + ....... + + // CMP pseudocode procedure + if (cmpManager.hasConsent()) { + AppsFlyer.startSDK(); + } else { + cmpManager.presentConsentDialogToUser() + .then(res => AppsFlyer.startSDK()) +} +``` + +## Manually collect consent data +If your app does not use a CMP compatible with TCF v2.2, use the SDK API detailed below to provide the consent data directly to the SDK, distinguishing between cases when GDPR applies or not. + +### When GDPR applies to the user +If GDPR applies to the user, perform the following: + +1. Given that GDPR is applicable to the user, determine whether the consent data is already stored for this session. + 1. If there is no consent data stored, show the consent dialog to capture the user consent decision. + 2. If there is consent data stored continue to the next step. +2. To transfer the consent data to the SDK create an AppsFlyerConsent object using `forGDPRUser` method that accepts the following parameters:
+ `hasConsentForDataUsage: boolean` - Indicates whether the user has consented to use their data for advertising purposes.
+ `hasConsentForAdsPersonalization: boolean` - Indicates whether the user has consented to use their data for personalized advertising. +3. Call `AppsFlyer.setConsentData(consentData)` with the AppsFlyerConsent object. +4. Call `AppsFlyer.initSdk()`. +```typescript + // If the user is subject to GDPR - collect the consent data + // or retrieve it from the storage + ...... + // Set the consent data to the SDK: + let gdprConsent = AppsFlyerConsent.forGDPRUser(true, false); + + AppsFlyer.setConsentData({data : gdprConsent}); + + AppsFlyer.initSDK({ + appID: '1234567890', + devKey: 'your_dev_key', + isDebug: true, + registerOnDeepLink: true, + minTimeBetweenSessions: 6, + registerConversionListener: true, + registerOnAppOpenAttribution: false, + useReceiptValidationSandbox: true, + useUninstallSandbox: true, + }); + ....... +``` + +### When GDPR does not apply to the user + +If GDPR doesn’t apply to the user perform the following: +1. Create an AppsFlyerConsent object using `forNonGDPRUser` method that doesn't accepts any parameters. +2. Call `AppsFlyer.setConsentData(consentData)` with the AppsFlyerConsent object. +3. Call `AppsFlyer.initSdk()`. +```typescript + // If the user is not subject to GDPR: + let nonGdprUserConsentData = AppsFlyerConsent.forNonGDPRUser(); + + AppsFlyer.setConsentData({data : nonGdprUserConsentData}); + + AppsFlyer.initSDK({ + appID: '1234567890', + devKey: 'your_dev_key', + isDebug: true, + registerOnDeepLink: true, + minTimeBetweenSessions: 6, + registerConversionListener: true, + registerOnAppOpenAttribution: false, + useReceiptValidationSandbox: true, + useUninstallSandbox: true, + }); + ....... +``` + + diff --git a/examples/CapacitorReact/package.json b/examples/CapacitorReact/package.json index 413a653..70c7bcb 100644 --- a/examples/CapacitorReact/package.json +++ b/examples/CapacitorReact/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "dependencies": { - "@capacitor/android": "5.7.0", + "@capacitor/android": "^5.0.0", "@capacitor/app": "^5.0.0", "@capacitor/core": "^5.0.0", "@capacitor/haptics": "^5.0.0", diff --git a/src/definitions.ts b/src/definitions.ts index 1ca0aed..15cec01 100644 --- a/src/definitions.ts +++ b/src/definitions.ts @@ -67,7 +67,7 @@ export interface AppsFlyerPlugin { initSDK(options: AFInit): Promise; /** - * Use this method to start AppsFlyer SDK, only on manual init mode. + * Use this method to start AppsFlyer SDK, only on manual start mode. */ startSDK(): Promise; From 39f26386c7046b0a01122f42ee6e9b8b054b5866 Mon Sep 17 00:00:00 2001 From: Dani Kozachkevich Date: Mon, 26 Feb 2024 19:02:21 +0200 Subject: [PATCH 08/14] fix code according to review --- .../capacitor/plugin/appsflyer/sdk/AppsFlyerPlugin.kt | 8 ++------ ios/Plugin/AppsFlyerPlugin.m | 4 ++-- ios/Plugin/AppsFlyerPlugin.swift | 7 +------ src/definitions.ts | 2 +- 4 files changed, 6 insertions(+), 15 deletions(-) diff --git a/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerPlugin.kt b/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerPlugin.kt index 3ca0f04..4a4796a 100644 --- a/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerPlugin.kt +++ b/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerPlugin.kt @@ -90,12 +90,10 @@ class AppsFlyerPlugin : Plugin() { } if (manualStart == false) { - Log.d("appsflyer_", "manual start: $manualStart") startSDK(call) } else { val result = JSObject().apply { - put("success", true) - put("msg", "SDK initiated successfully. SDK has NOT been started yet") + put("res", "SDK initiated successfully. SDK has NOT been started yet") } call.resolve(result) } @@ -547,9 +545,7 @@ class AppsFlyerPlugin : Plugin() { @PluginMethod(returnType = PluginMethod.RETURN_NONE) fun setConsentData(call: PluginCall) { - val consentData = call.getObject("data") ?: return with (call) { - reject("Missing consent data") - } + val consentData = call.getObject("data") ?: return call.reject("Missing consent data") val isUserSubjectToGDPR = consentData.optBoolean(AF_IS_SUBJECTED_TO_GDPR) val hasConsentForDataUsage = consentData.optBoolean(AF_CONSENT_FOR_DATA_USAGE) diff --git a/ios/Plugin/AppsFlyerPlugin.m b/ios/Plugin/AppsFlyerPlugin.m index 7f6bf60..4d5cbc8 100644 --- a/ios/Plugin/AppsFlyerPlugin.m +++ b/ios/Plugin/AppsFlyerPlugin.m @@ -39,8 +39,8 @@ CAP_PLUGIN_METHOD(logInvite, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(setSharingFilterForPartners, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(enableTCFDataCollection, CAPPluginReturnPromise); - CAP_PLUGIN_METHOD(setConsentData, CAPPluginReturnPromise); - CAP_PLUGIN_METHOD(startSDK, CAPPluginReturnPromise); + CAP_PLUGIN_METHOD(setConsentData, CAPPluginReturnNone); + CAP_PLUGIN_METHOD(startSDK, CAPPluginReturnNone); diff --git a/ios/Plugin/AppsFlyerPlugin.swift b/ios/Plugin/AppsFlyerPlugin.swift index bb85a44..8c5163a 100644 --- a/ios/Plugin/AppsFlyerPlugin.swift +++ b/ios/Plugin/AppsFlyerPlugin.swift @@ -74,12 +74,7 @@ public class AppsFlyerPlugin: CAPPlugin { if !manualStart { startSDK(call) } else { - let result = [ - "success": true, - "msg": "SDK initiated successfully. SDK has NOT been started yet" - ] as [String: Any] - - call.resolve(result) + call.resolve(["res": "SDK initiated successfully. SDK has NOT started yet"]) } } diff --git a/src/definitions.ts b/src/definitions.ts index 15cec01..c94c2e5 100644 --- a/src/definitions.ts +++ b/src/definitions.ts @@ -253,7 +253,7 @@ export interface AppsFlyerPlugin { * * @param disable Defaults to false */ - setDisableNetmanualStartworkData(disable : AFDisable): Promise; + setDisableNetworkData(disable : AFDisable): Promise; /** * Use to opt-in/out the automatic collection of consent data, for users who use a CMP. From 1a131f9331518e3361e3830bccbc9298a1f46b5a Mon Sep 17 00:00:00 2001 From: Dani Kozachkevich Date: Mon, 26 Feb 2024 19:27:22 +0200 Subject: [PATCH 09/14] removed unnecessary import, fixed according to review --- .../plugin/appsflyer/sdk/AppsFlyerPlugin.kt | 1 - docs/API.md | 46 ++++++++++--------- ios/Plugin/AppsFlyerPlugin.m | 2 +- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerPlugin.kt b/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerPlugin.kt index 4a4796a..e6f7ec2 100644 --- a/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerPlugin.kt +++ b/android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerPlugin.kt @@ -2,7 +2,6 @@ package capacitor.plugin.appsflyer.sdk import android.Manifest import android.content.Intent -import android.util.Log import com.appsflyer.* import com.appsflyer.attribution.AppsFlyerRequestListener diff --git a/docs/API.md b/docs/API.md index 70c71cc..1efdfbc 100644 --- a/docs/API.md +++ b/docs/API.md @@ -56,9 +56,9 @@ The list of available methods for this plugin is described below. * [`setSharingFilterForPartners`](#setsharingfilterforpartners) * [`setSharingFilter`](#setsharingfilter) - Deprecated * [`setSharingFilterForAllPartners`](#setsharingfilterforallpartners) - Deprecated -* [`startSDK`](#startSDK) - New -* [`enableTCFDataCollection`](#enableTCFDataCollection) - New -* [`setConsentData`](#setConsentData) - New +* [`startSDK`](#startSDK) - Since 6.13.0 +* [`enableTCFDataCollection`](#enableTCFDataCollection) - Since 6.13.0 +* [`setConsentData`](#setConsentData) - Since 6.13.0 @@ -184,7 +184,27 @@ See also Init SDK guide [here](/Guides.md#init-sdk). -------------------- - + + +### startSDK +```typescript +startSDK(): Promise; +``` + +Use this method to start AppsFlyer SDK only on manual start mode. + +**Returns:** Promise<AFRes> + +**Usage Example:** +```typescript + AppsFlyer.startSDK() + .then(res => console.log("AppsFlyer SDK Start Response: ", res.res)) + .catch(err => console.error("AppsFlyer SDK Start Error: ", err)); +``` + + +-------------------- + ### logEvent @@ -914,24 +934,6 @@ Use to log a user-invite in-app event (af_invite). -------------------- -### startSDK -```typescript -startSDK(): Promise; -``` - -Use this method to start AppsFlyer SDK, available only on manual start mode. - -**Returns:** Promise<AFRes> - -**Usage Example:** -```typescript - AppsFlyer.startSDK() - .then(res => console.log("AppsFlyer SDK Start Response: ", res.res)) - .catch(err => console.error("AppsFlyer SDK Start Error: ", err)); -``` - --------------------- - ### enableTCFDataCollection ```typescript enableTCFDataCollection(shouldEnableTCFDataCollection: AFEnableTCFDataCollection): Promise diff --git a/ios/Plugin/AppsFlyerPlugin.m b/ios/Plugin/AppsFlyerPlugin.m index 4d5cbc8..71b81e9 100644 --- a/ios/Plugin/AppsFlyerPlugin.m +++ b/ios/Plugin/AppsFlyerPlugin.m @@ -40,7 +40,7 @@ CAP_PLUGIN_METHOD(setSharingFilterForPartners, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(enableTCFDataCollection, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(setConsentData, CAPPluginReturnNone); - CAP_PLUGIN_METHOD(startSDK, CAPPluginReturnNone); + CAP_PLUGIN_METHOD(startSDK, CAPPluginReturnPromise); From f2cb9a0c5f41730cf2ff0b27e9d27b985f4e791b Mon Sep 17 00:00:00 2001 From: Dani Kozachkevich Date: Mon, 26 Feb 2024 19:31:50 +0200 Subject: [PATCH 10/14] fixed according to code review --- ios/Plugin/AppsFlyerPlugin.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/Plugin/AppsFlyerPlugin.m b/ios/Plugin/AppsFlyerPlugin.m index 71b81e9..e25d470 100644 --- a/ios/Plugin/AppsFlyerPlugin.m +++ b/ios/Plugin/AppsFlyerPlugin.m @@ -38,7 +38,7 @@ CAP_PLUGIN_METHOD(setPartnerData, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(logInvite, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(setSharingFilterForPartners, CAPPluginReturnPromise); - CAP_PLUGIN_METHOD(enableTCFDataCollection, CAPPluginReturnPromise); + CAP_PLUGIN_METHOD(enableTCFDataCollection, CAPPluginReturnNone); CAP_PLUGIN_METHOD(setConsentData, CAPPluginReturnNone); CAP_PLUGIN_METHOD(startSDK, CAPPluginReturnPromise); From 6c682da101c4381dca7ae839e8ed973e79c38414 Mon Sep 17 00:00:00 2001 From: Paz Lavi Date: Mon, 26 Feb 2024 20:26:52 +0200 Subject: [PATCH 11/14] Revert "change to buildDir" This reverts commit 67aedfb988b9326269458a08796951db8bcf4e46. --- android/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/build.gradle b/android/build.gradle index d2eddbf..ac71624 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -7,7 +7,7 @@ import java.nio.file.SimpleFileVisitor import java.nio.file.attribute.BasicFileAttributes String getPackageJsonPath() { - return findProperty("APPSFLYER_PACKAGE_JSON") ?: "$buildDir/../node_modules/appsflyer-capacitor-plugin/package.json" + return findProperty("APPSFLYER_PACKAGE_JSON") ?: "$rootDir/../node_modules/appsflyer-capacitor-plugin/package.json" } def findNodeModulesDir(File currentDir) { From d26a5fae9049c28a4aa4a56b4e788984288dc6a8 Mon Sep 17 00:00:00 2001 From: pazlavi Date: Mon, 26 Feb 2024 18:57:45 +0000 Subject: [PATCH 12/14] update versions using CI --- ios/Plugin/AppsFlyerPlugin.swift | 2 +- package.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ios/Plugin/AppsFlyerPlugin.swift b/ios/Plugin/AppsFlyerPlugin.swift index 8c5163a..1796690 100644 --- a/ios/Plugin/AppsFlyerPlugin.swift +++ b/ios/Plugin/AppsFlyerPlugin.swift @@ -5,7 +5,7 @@ import AppsFlyerLib @objc(AppsFlyerPlugin) public class AppsFlyerPlugin: CAPPlugin { - private let APPSFLYER_PLUGIN_VERSION = "6.12.1" + private let APPSFLYER_PLUGIN_VERSION = "6.13.0-rc1" private var conversion = true private var oaoa = true private var udl = false diff --git a/package.json b/package.json index 527091e..8ccd5ce 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { "name": "appsflyer-capacitor-plugin", - "version": "6.13.0", + "version": "6.13.0-rc1", "iosSdkVersion": "6.13.0", "androidSdkVersion": "6.13.0", - "buildNumber": "10", + "buildNumber": "82", "description": "AppsFlyer SDK plugin for Capacitor", "main": "dist/plugin.cjs.js", "module": "dist/esm/index.js", From 94d5608b42c74e67241865e36e84e59283989377 Mon Sep 17 00:00:00 2001 From: pazlavi Date: Mon, 26 Feb 2024 19:31:08 +0000 Subject: [PATCH 13/14] Update Plugin Version --- ios/Plugin/AppsFlyerPlugin.swift | 2 +- package.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ios/Plugin/AppsFlyerPlugin.swift b/ios/Plugin/AppsFlyerPlugin.swift index 1796690..f6627c2 100644 --- a/ios/Plugin/AppsFlyerPlugin.swift +++ b/ios/Plugin/AppsFlyerPlugin.swift @@ -5,7 +5,7 @@ import AppsFlyerLib @objc(AppsFlyerPlugin) public class AppsFlyerPlugin: CAPPlugin { - private let APPSFLYER_PLUGIN_VERSION = "6.13.0-rc1" + private let APPSFLYER_PLUGIN_VERSION = "6.13.0" private var conversion = true private var oaoa = true private var udl = false diff --git a/package.json b/package.json index 8ccd5ce..a910d90 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { "name": "appsflyer-capacitor-plugin", - "version": "6.13.0-rc1", + "version": "6.13.0", "iosSdkVersion": "6.13.0", "androidSdkVersion": "6.13.0", - "buildNumber": "82", + "buildNumber": "11", "description": "AppsFlyer SDK plugin for Capacitor", "main": "dist/plugin.cjs.js", "module": "dist/esm/index.js", From c6baa8941bfdc99a8a4b701fadf76cb7d91381ac Mon Sep 17 00:00:00 2001 From: pazlavi Date: Mon, 26 Feb 2024 19:31:10 +0000 Subject: [PATCH 14/14] Update CHANGELOG.md --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d474e5b..9ca2490 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 6.13.0 + Release date: *2024-02-26* + +- Capacitor >> MonoRepo structure project >> failed to build on Android since v6.10.3 + ## 6.12.1 Release date: *2023-07-31*