Skip to content

Commit

Permalink
Merge pull request #116 from AppsFlyerSDK/releases/6.x.x/6.13.x/6.13.…
Browse files Browse the repository at this point in the history
…0-rc1

Merge releases/6.x.x/6.13.x/6.13.0-rc1 into main
  • Loading branch information
Dani-Koza-AF authored Feb 26, 2024
2 parents d70c1b7 + c6baa89 commit 4760917
Show file tree
Hide file tree
Showing 15 changed files with 471 additions and 42 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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*

Expand Down
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@

### <a id="plugin-build-for"> 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**

## <a id="breaking-changes-6-12-1"> ❗❗ Breaking changes when updating to v6.12.1❗❗
## <a id="breaking-changes-6-12-1"> ❗❗ Breaking changes when updating to v6.12.1 ❗❗
Starting from v6.12.1, this plugin works only with Capacitor 5. </br>
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.



## <a id="breaking-changes"> ❗❗ Breaking changes when updating to v6.9.2❗❗
## <a id="breaking-changes"> ❗❗ Breaking changes when updating to v6.9.2 ❗❗
Starting from v6.9.2, this plugin works only with Capacitor 4. </br>
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.

Expand All @@ -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)
74 changes: 69 additions & 5 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -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<Path>() {
@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
Expand All @@ -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"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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_GDPR = "isUserSubjectToGDPR"
const val AF_CONSENT_FOR_DATA_USAGE = "hasConsentForDataUsage"
const val AF_CONSENT_FOR_ADS_PERSONALIZATION = "hasConsentForAdsPersonalization"

Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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) {
Expand All @@ -86,18 +87,15 @@ 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("res", "SDK initiated successfully. SDK has NOT been started yet")
}

})
call.resolve(result)
}
}

}
Expand Down Expand Up @@ -284,6 +282,23 @@ class AppsFlyerPlugin : Plugin() {
}
}

@PluginMethod
fun startSDK(call: PluginCall) {
AppsFlyerLib.getInstance()
.start(activity ?: context.applicationContext, null, object : AppsFlyerRequestListener {
override fun onSuccess() {
val result = JSObject().apply {
put("res", "success")
}
call.resolve(result)
}

override fun onError(errCode: Int, msg: String) {
call.reject("Error Code: $errCode, Message: $msg")
}
})
}

@PluginMethod
fun disableSKAdNetwork(call: PluginCall) {
call.unavailable()
Expand Down Expand Up @@ -517,6 +532,35 @@ 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 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)
val hasConsentForAdsPersonalization = consentData.optBoolean(AF_CONSENT_FOR_ADS_PERSONALIZATION)

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) {
Expand Down
95 changes: 94 additions & 1 deletion docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -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) - Since 6.13.0
* [`enableTCFDataCollection`](#enableTCFDataCollection) - Since 6.13.0
* [`setConsentData`](#setConsentData) - Since 6.13.0



</docgen-index>
Expand Down Expand Up @@ -180,7 +184,27 @@ See also Init SDK guide [here](/Guides.md#init-sdk).


--------------------



### startSDK
```typescript
startSDK(): Promise<AFRes>;
```

Use this method to start AppsFlyer SDK only on manual start mode.

**Returns:** <code>Promise<<a href="#aFRes">AFRes</a>></code>

**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

Expand Down Expand Up @@ -908,6 +932,55 @@ Use to log a user-invite in-app event (af_invite).
.catch(e => console.log(e));
```

--------------------

### enableTCFDataCollection
```typescript
enableTCFDataCollection(shouldEnableTCFDataCollection: AFEnableTCFDataCollection): Promise<void>
```

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`** | <code><a href="#AFEnableTCFDataCollection">AFEnableTCFDataCollection</a></code> |

**Returns:** <code>Promise</code>

**Usage Example:**
```typescript
AppsFlyer.enableTCFDataCollection({shouldEnableTCFDataCollection : <true/false>})
```

--------------------

### setConsentData
```typescript
setConsentData(data : AFConsentData): Promise<void>
```

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`** | <code><a href="#AFConsentData">AFConsentData</a></code> |

**Returns:** <code>Promise</code>

**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(<true/false>, <true/false>)});
```
*Please take a look how to properly setConsentData Manualy in [Set Consent For DMA Compliance](/docs/DMA.md#)*


## Interfaces


Expand Down Expand Up @@ -1193,6 +1266,26 @@ Use to log a user-invite in-app event (af_invite).
| **`eventParameters`** | <code><a href="#stringmap">StringMap</a></code> |
| **`channel`** | <code>string</code>|

#### AFEnableTCFDataCollection

| Prop | Type |
| ----------------- | ----------------------------------------------- |
| **`shouldEnableTCFDataCollection`** | <code>boolean</code>|

#### AFConsentData

| Prop | Type |
| ----------------- | ----------------------------------------------- |
| **`data`** | <code><a href="#IAppsFlyerConsent">IAppsFlyerConsent</a></code>|

#### IAppsFlyerConsent

| Prop | Type |
| ----------------- | ----------------------------------------------- |
| **`isUserSubjectToGDPR`** | <code>boolean</code>|
| **`hasConsentForDataUsage`** | <code>boolean</code>|
| **`hasConsentForAdsPersonalization`** | <code>boolean</code>|

## Enums


Expand Down
Loading

0 comments on commit 4760917

Please sign in to comment.