From 02e335e34dd82d732b641d5dafed7241b9f177f6 Mon Sep 17 00:00:00 2001 From: gabriel mandler Date: Sun, 11 Jun 2023 16:11:22 +0300 Subject: [PATCH 01/12] fix for send push notification for ios . added new API sendPushNotificationData --- .gitignore | 12 +++++ .../appsflyersdk/AppsflyerSdkPlugin.java | 8 +++ doc/API.md | 42 ++++++++++++++- example/.metadata | 45 ++++++++++++++-- .../res/drawable-v21/launch_background.xml | 12 +++++ .../app/src/main/res/values-night/styles.xml | 18 +++++++ example/ios/.gitignore | 34 +++++++++++++ example/ios/Podfile | 2 +- .../xcshareddata/WorkspaceSettings.xcsettings | 8 +++ example/ios/Runner/AppDelegate.swift | 13 +++++ example/ios/Runner/Info.plist | 51 +++++++++++++++++++ example/ios/Runner/Runner-Bridging-Header.h | 1 + ios/Classes/AppsflyerSdkPlugin.m | 12 +++-- lib/src/appsflyer_sdk.dart | 4 ++ 14 files changed, 250 insertions(+), 12 deletions(-) create mode 100644 example/android/app/src/main/res/drawable-v21/launch_background.xml create mode 100644 example/android/app/src/main/res/values-night/styles.xml create mode 100644 example/ios/.gitignore create mode 100644 example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 example/ios/Runner/AppDelegate.swift create mode 100644 example/ios/Runner/Info.plist create mode 100644 example/ios/Runner/Runner-Bridging-Header.h diff --git a/.gitignore b/.gitignore index 57582a9..2692b13 100644 --- a/.gitignore +++ b/.gitignore @@ -97,6 +97,18 @@ example/ios/Runner.xcodeproj/project.pbxproj example/.flutter-plugins-dependencies +example/macos/* + +example/linux/* + +example/windows/* + +example/web/* + +example/\.metadata +example/analysis_options.yaml + + node_modules/ covBadgeGen.js diff --git a/android/src/main/java/com/appsflyer/appsflyersdk/AppsflyerSdkPlugin.java b/android/src/main/java/com/appsflyer/appsflyersdk/AppsflyerSdkPlugin.java index 6c7d85b..78a8a8e 100644 --- a/android/src/main/java/com/appsflyer/appsflyersdk/AppsflyerSdkPlugin.java +++ b/android/src/main/java/com/appsflyer/appsflyersdk/AppsflyerSdkPlugin.java @@ -289,6 +289,9 @@ public void onMethodCall(MethodCall call, Result result) { setOneLinkCustomDomain(call, result); break; case "setPushNotification": + setPushNotification(call, result); + break; + case "sendPushNotificationData": sendPushNotificationData(call, result); break; case "enableFacebookDeferredApplinks": @@ -398,6 +401,11 @@ private void enableFacebookDeferredApplinks(MethodCall call, Result result) { result.success(null); } + private void setPushNotification(MethodCall call, Result result) { + AppsFlyerLib.getInstance().sendPushNotificationData(activity); + result.success(null); + } + private void sendPushNotificationData(MethodCall call, Result result) { AppsFlyerLib.getInstance().sendPushNotificationData(activity); result.success(null); diff --git a/doc/API.md b/doc/API.md index 0479117..af99939 100644 --- a/doc/API.md +++ b/doc/API.md @@ -32,7 +32,8 @@ - [getHostPrefix](#getHostPrefix) - [updateServerUninstallToken](#updateServerUninstallToken) - [Validate Purchase](#validatePurchase) -- [setPushNotification](#setPushNotification) +- [setPushNotification](#setPushNotification)[DEPRECATED] +- [sendPushNotificationData](#sendPushNotificationData) - [addPushNotificationDeepLinkPath](#addPushNotificationDeepLinkPath) - [User Invite](#userInvite) - [enableFacebookDeferredApplinks](#enableFacebookDeferredApplinks) @@ -400,7 +401,7 @@ appsflyerSdk.onPurchaseValidation((res){ ``` --- -** `void setPushNotification(bool isEnabled)`** +** `void setPushNotification(bool isEnabled)`[DEPRECATED]** _Example:_ ```dart @@ -417,6 +418,43 @@ Please check the following guide in order to understand the relevant payload nee https://support.appsflyer.com/hc/en-us/articles/207364076-Measuring-push-notification-re-engagement-campaigns +--- +** `void sendPushNotificationData(Map? userInfo)`** + +For Android: Make sure to call this API inside the page of every activity that is launched after clicking the notification. + +For iOS: This API can be called in the pus notification listener. + +Please check the following guide in order to understand the relevant payload needed for AppsFlyer to attribute the push notification: + +https://support.appsflyer.com/hc/en-us/articles/207364076-Measuring-push-notification-re-engagement-campaigns + + +_Example:_ +```dart +final Map userInfo = { + "af":{ + "c": "test_campaign", + "is_retargeting": true, + "pid": "push_provider_int", + }, + "aps":{ + "alert": "Get 5000 Coins", + "badge": "37", + "sound": "default" + } + }; + +appsFlyerSdk.sendPushNotificationData(userInfo); +``` + +Example for firebase: +```dart + FirebaseMessaging.onMessage.listen((RemoteMessage message) { + appsflyerSdk.sendPushNotificationData(message.data); + }); +``` + --- ** `void addPushNotificationDeepLinkPath(List deeplinkPath)`** diff --git a/example/.metadata b/example/.metadata index fbaf7fa..262ceed 100644 --- a/example/.metadata +++ b/example/.metadata @@ -1,8 +1,45 @@ -# This file log properties of this Flutter project. +# This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # -# This file should be version controlled and should not be manually edited. +# This file should be version controlled. version: - revision: f37c235c32fc15babe6dc7b7bc2ee4387e5ecf92 - channel: beta + revision: 135454af32477f815a7525073027a3ff9eff1bfd + channel: stable + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 135454af32477f815a7525073027a3ff9eff1bfd + base_revision: 135454af32477f815a7525073027a3ff9eff1bfd + - platform: android + create_revision: 135454af32477f815a7525073027a3ff9eff1bfd + base_revision: 135454af32477f815a7525073027a3ff9eff1bfd + - platform: ios + create_revision: 135454af32477f815a7525073027a3ff9eff1bfd + base_revision: 135454af32477f815a7525073027a3ff9eff1bfd + - platform: linux + create_revision: 135454af32477f815a7525073027a3ff9eff1bfd + base_revision: 135454af32477f815a7525073027a3ff9eff1bfd + - platform: macos + create_revision: 135454af32477f815a7525073027a3ff9eff1bfd + base_revision: 135454af32477f815a7525073027a3ff9eff1bfd + - platform: web + create_revision: 135454af32477f815a7525073027a3ff9eff1bfd + base_revision: 135454af32477f815a7525073027a3ff9eff1bfd + - platform: windows + create_revision: 135454af32477f815a7525073027a3ff9eff1bfd + base_revision: 135454af32477f815a7525073027a3ff9eff1bfd + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/example/android/app/src/main/res/drawable-v21/launch_background.xml b/example/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000..f74085f --- /dev/null +++ b/example/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/example/android/app/src/main/res/values-night/styles.xml b/example/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..06952be --- /dev/null +++ b/example/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/example/ios/.gitignore b/example/ios/.gitignore new file mode 100644 index 0000000..7a7f987 --- /dev/null +++ b/example/ios/.gitignore @@ -0,0 +1,34 @@ +**/dgph +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/ephemeral/ +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/example/ios/Podfile b/example/ios/Podfile index f7d6a5e..d207307 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -# platform :ios, '9.0' +# platform :ios, '11.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/example/ios/Runner/AppDelegate.swift b/example/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..70693e4 --- /dev/null +++ b/example/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import UIKit +import Flutter + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist new file mode 100644 index 0000000..7f55346 --- /dev/null +++ b/example/ios/Runner/Info.plist @@ -0,0 +1,51 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Example + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + example + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + CADisableMinimumFrameDurationOnPhone + + UIApplicationSupportsIndirectInputEvents + + + diff --git a/example/ios/Runner/Runner-Bridging-Header.h b/example/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..308a2a5 --- /dev/null +++ b/example/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/ios/Classes/AppsflyerSdkPlugin.m b/ios/Classes/AppsflyerSdkPlugin.m index cd2cdce..c576a22 100644 --- a/ios/Classes/AppsflyerSdkPlugin.m +++ b/ios/Classes/AppsflyerSdkPlugin.m @@ -122,7 +122,9 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { }else if([@"setOneLinkCustomDomain" isEqualToString:call.method]){ [self setOneLinkCustomDomain:call result:result]; }else if([@"setPushNotification" isEqualToString:call.method]){ - [self setPushNotification:call result:result]; + [self setPushNotification:call result:result]; + }else if([@"sendPushNotificationData" isEqualToString:call.method]){ + [self sendPushNotificationData:call result:result]; }else if([@"useReceiptValidationSandbox" isEqualToString:call.method]){ [self useReceiptValidationSandbox:call result:result]; }else if([@"enableFacebookDeferredApplinks" isEqualToString:call.method]){ @@ -231,10 +233,10 @@ - (void)setPushNotification:(FlutterMethodCall*)call result:(FlutterResult)resul result(nil); } -- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { - if(_isPushNotificationEnabled){ - [[AppsFlyerLib shared] handlePushNotification:userInfo]; - } +- (void)sendPushNotificationData:(FlutterMethodCall*)call result:(FlutterResult)result{ + NSDictionary* userInfo = call.arguments; + [[AppsFlyerLib shared] handlePushNotification:userInfo]; + result(nil); } - (void)setOneLinkCustomDomain:(FlutterMethodCall*)call result:(FlutterResult)result{ diff --git a/lib/src/appsflyer_sdk.dart b/lib/src/appsflyer_sdk.dart index 512d7fb..0e36241 100644 --- a/lib/src/appsflyer_sdk.dart +++ b/lib/src/appsflyer_sdk.dart @@ -403,6 +403,10 @@ class AppsflyerSdk { _methodChannel.invokeMethod("setPushNotification", isEnabled); } + void sendPushNotificationData(Map? userInfo) { + _methodChannel.invokeMethod("sendPushNotificationData", userInfo); + } + void enableFacebookDeferredApplinks(bool isEnabled) { _methodChannel.invokeMethod("enableFacebookDeferredApplinks", {'isFacebookDeferredApplinksEnabled': isEnabled}); From 586c1f22593bbff0b49a7e60b253c43124f4b8ba Mon Sep 17 00:00:00 2001 From: gabriel mandler Date: Sun, 11 Jun 2023 16:22:01 +0300 Subject: [PATCH 02/12] docs update --- README.md | 2 ++ doc/API.md | 14 ++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f828746..da5e191 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,8 @@ If you have used one of the removed/changed APIs, please check the integration guide for the updated instructions. +- From version `6.11.2`, the `setPushNotification` will not work in iOS. [Please use new API sendPushNotificationData when receiving a notification on flutter side](/doc/API.md#sendPushNotificationData). + - From version `6.8.0`, the `enableLocationCollection` has been removed from the plugin. - From version `6.4.0`, UDL (Unified deep link) now as a dedicated class with getters for handling the deeplink result. diff --git a/doc/API.md b/doc/API.md index af99939..6095ed3 100644 --- a/doc/API.md +++ b/doc/API.md @@ -421,16 +421,17 @@ https://support.appsflyer.com/hc/en-us/articles/207364076-Measuring-push-notific --- ** `void sendPushNotificationData(Map? userInfo)`** -For Android: Make sure to call this API inside the page of every activity that is launched after clicking the notification. +For Android: Make sure to call this API inside the page of every activity that is launched after clicking the notification. +Pass null as an argument. -For iOS: This API can be called in the pus notification listener. +For iOS: This API should be called in the push notification listener. Please check the following guide in order to understand the relevant payload needed for AppsFlyer to attribute the push notification: https://support.appsflyer.com/hc/en-us/articles/207364076-Measuring-push-notification-re-engagement-campaigns -_Example:_ +_iOS Example:_ ```dart final Map userInfo = { "af":{ @@ -448,13 +449,18 @@ final Map userInfo = { appsFlyerSdk.sendPushNotificationData(userInfo); ``` -Example for firebase: +iOS with firebase: ```dart FirebaseMessaging.onMessage.listen((RemoteMessage message) { appsflyerSdk.sendPushNotificationData(message.data); }); ``` +Example for Android: +```dart + appsflyerSdk.sendPushNotificationData(null); +``` + --- ** `void addPushNotificationDeepLinkPath(List deeplinkPath)`** From 1db0b750d82fd0c277db1b2fbd51fd039c15c274 Mon Sep 17 00:00:00 2001 From: gabriel mandler Date: Sun, 11 Jun 2023 16:25:52 +0300 Subject: [PATCH 03/12] appsflyer options api page doc update --- doc/API.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/doc/API.md b/doc/API.md index 6095ed3..f2c81ec 100644 --- a/doc/API.md +++ b/doc/API.md @@ -59,11 +59,18 @@ **`options`** -| name | type | default | description | -| ---------- | --------- | ------- | ------------------------------------------------------------------------------------------------------------------------------ | -| `afDevKey` | `String` | | [Appsflyer Dev key](https://support.appsflyer.com/hc/en-us/articles/207032126-AppsFlyer-SDK-Integration-Android) | -| `afAppId` | `String` | | [Apple Application ID](https://support.appsflyer.com/hc/en-us/articles/207032066-AppsFlyer-SDK-Integration-iOS) (for iOS only) | -| `showDebug` | `bool` | `false` | debug mode (optional) | + | +| Setting | Type | Description | +| -------- | -------- | ------------- | +| devKey | String | Your application's [devKey](https://support.appsflyer.com/hc/en-us/articles/207032066-Basic-SDK-integration-guide#retrieving-the-dev-key) provided by AppsFlyer (required) | +| appId | String | Your application's [App ID](https://support.appsflyer.com/hc/en-us/articles/207377436-Adding-a-new-app#available-in-the-app-store-google-play-store-windows-phone-store) (required for iOS only) that you configured in your AppsFlyer dashboard | +| showDebug | bool | Debug mode - set to `true` for testing only, do not release to production with this parameter set to `true`! | +| timeToWaitForATTUserAuthorization | double | Delays the SDK start for x seconds until the user either accepts the consent dialog, declines it, or the timer runs out. | +| appInviteOneLink | String | The [OneLink template ID](https://support.appsflyer.com/hc/en-us/articles/115004480866-User-invite-attribution#parameters) that is used to generate a User Invite, this is not a required field in the `AppsFlyerOptions`, you may choose to set it later via the appropriate API. | +| disableAdvertisingIdentifier| bool | Opt-out of the collection of Advertising Identifiers, which include OAID, AAID, GAID and IDFA. | +| disableCollectASA | bool | Opt-out of the Apple Search Ads attributions. | + + _Example:_ From b081cdfdea8c710c4be16653bc3dddd944f7d74f Mon Sep 17 00:00:00 2001 From: gabriel mandler Date: Mon, 12 Jun 2023 12:55:22 +0300 Subject: [PATCH 04/12] fix for android push notification API --- README.md | 2 +- .../appsflyersdk/AppsflyerSdkPlugin.java | 47 ++++++++++++++++++- doc/API.md | 35 ++------------ 3 files changed, 50 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index da5e191..100bc79 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ If you have used one of the removed/changed APIs, please check the integration guide for the updated instructions. -- From version `6.11.2`, the `setPushNotification` will not work in iOS. [Please use new API sendPushNotificationData when receiving a notification on flutter side](/doc/API.md#sendPushNotificationData). +- From version `6.11.2`, the `setPushNotification` will not work in iOS. [Please use our new API `sendPushNotificationData` when receiving a notification on flutter side](/doc/API.md#sendPushNotificationData). - From version `6.8.0`, the `enableLocationCollection` has been removed from the plugin. diff --git a/android/src/main/java/com/appsflyer/appsflyersdk/AppsflyerSdkPlugin.java b/android/src/main/java/com/appsflyer/appsflyersdk/AppsflyerSdkPlugin.java index 78a8a8e..389d048 100644 --- a/android/src/main/java/com/appsflyer/appsflyersdk/AppsflyerSdkPlugin.java +++ b/android/src/main/java/com/appsflyer/appsflyersdk/AppsflyerSdkPlugin.java @@ -4,6 +4,7 @@ import android.app.Application; import android.content.Context; import android.content.Intent; +import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.util.Log; @@ -407,10 +408,52 @@ private void setPushNotification(MethodCall call, Result result) { } private void sendPushNotificationData(MethodCall call, Result result) { - AppsFlyerLib.getInstance().sendPushNotificationData(activity); + final Map pushPayload = (Map) call.arguments; + String errorMsg = null; + Bundle bundle; + + if(pushPayload == null){ + Log.d("AppsFlyer", "Push payload is null"); + return; + } + + try { + bundle = this.jsonToBundle(new JSONObject(pushPayload)); + } catch (JSONException e) { + Log.d("AppsFlyer", "Can't parse pushPayload to bundle"); + return; + } + + if (activity != null) { + Intent intent = activity.getIntent(); + if (intent != null) { + intent.putExtras(bundle); + activity.setIntent(intent); + AppsFlyerLib.getInstance().sendPushNotificationData(activity); + } else { + errorMsg = "The intent is null. Push payload has not been sent!"; + } + } else { + errorMsg = "The activity is null. Push payload has not been sent!"; + } + + if(errorMsg != null){ + Log.d("AppsFlyer", errorMsg); + return; + } + result.success(null); } - + private static Bundle jsonToBundle(JSONObject jsonObject) throws JSONException { + Bundle bundle = new Bundle(); + Iterator iter = jsonObject.keys(); + while (iter.hasNext()) { + String key = (String) iter.next(); + String value = jsonObject.getString(key); + bundle.putString(key, value); + } + return bundle; + } private void setOneLinkCustomDomain(MethodCall call, Result result) { ArrayList brandDomains = (ArrayList) call.arguments; String[] brandDomainsArray = brandDomains.toArray(new String[brandDomains.size()]); diff --git a/doc/API.md b/doc/API.md index f2c81ec..314fb9e 100644 --- a/doc/API.md +++ b/doc/API.md @@ -414,31 +414,16 @@ _Example:_ ```dart appsFlyerSdk.setPushNotification(true); ``` - -_NOTE:_ - -For Android: Make sure to call this API inside the page of every activity that is launched after clicking the notification. - -For iOS: This API can be called once at the initalization phase. - -Please check the following guide in order to understand the relevant payload needed for AppsFlyer to attribute the push notification: - -https://support.appsflyer.com/hc/en-us/articles/207364076-Measuring-push-notification-re-engagement-campaigns - --- ** `void sendPushNotificationData(Map? userInfo)`** -For Android: Make sure to call this API inside the page of every activity that is launched after clicking the notification. -Pass null as an argument. - -For iOS: This API should be called in the push notification listener. - -Please check the following guide in order to understand the relevant payload needed for AppsFlyer to attribute the push notification: +Push-notification campaigns are used to create fast re-engagements with existing users. -https://support.appsflyer.com/hc/en-us/articles/207364076-Measuring-push-notification-re-engagement-campaigns +[Learn more](https://support.appsflyer.com/hc/en-us/articles/207364076-Measuring-Push-Notification-Re-Engagement-Campaigns) +For Android: AppsFlyer SDK uses the activity in order to process the push payload. Make sure you call this api when the app's activity is available (NOT dead state). -_iOS Example:_ +_Example:_ ```dart final Map userInfo = { "af":{ @@ -456,18 +441,6 @@ final Map userInfo = { appsFlyerSdk.sendPushNotificationData(userInfo); ``` -iOS with firebase: -```dart - FirebaseMessaging.onMessage.listen((RemoteMessage message) { - appsflyerSdk.sendPushNotificationData(message.data); - }); -``` - -Example for Android: -```dart - appsflyerSdk.sendPushNotificationData(null); -``` - --- ** `void addPushNotificationDeepLinkPath(List deeplinkPath)`** From 359005b6ce6f6a74a6874e6e37494c272ca0859c Mon Sep 17 00:00:00 2001 From: gabriel mandler Date: Tue, 20 Jun 2023 12:24:29 +0300 Subject: [PATCH 05/12] update ios sdk to v6.11.2 --- CHANGELOG.md | 4 ++-- README.md | 2 +- ios/appsflyer_sdk.podspec | 2 +- pubspec.yaml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f75018..85f0704 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Versions -## 6.11.1 -- update to Android SDK to v6.11.1 +## 6.11.2 +- update to Android SDK to v6.11.1 and ios sdk v6.11.2 ## 6.10.1 - update to Android SDK to v6.10.3 & iOS SDK to v6.10.1 ## 6.9.3 diff --git a/README.md b/README.md index 100bc79..f9c3fe7 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ ### This plugin is built for - Android AppsFlyer SDK **v6.11.1** -- iOS AppsFlyer SDK **v6.10.1** +- iOS AppsFlyer SDK **v6.11.2** ## ❗❗ Breaking changes when updating to v6.x.x❗❗ diff --git a/ios/appsflyer_sdk.podspec b/ios/appsflyer_sdk.podspec index 5ce1c32..e062f11 100644 --- a/ios/appsflyer_sdk.podspec +++ b/ios/appsflyer_sdk.podspec @@ -21,6 +21,6 @@ AppsFlyer is the market leader in mobile advertising attribution & analytics, he s.source_files = 'Classes/**/*' s.public_header_files = 'Classes/**/*.h' s.dependency 'Flutter' - s.ios.dependency 'AppsFlyerFramework', '6.10.1' + s.ios.dependency 'AppsFlyerFramework', '6.11.2' end diff --git a/pubspec.yaml b/pubspec.yaml index 2020f0a..9ebbf35 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: appsflyer_sdk description: A Flutter plugin for AppsFlyer SDK. Supports iOS and Android. -version: 6.11.1 +version: 6.11.2 homepage: https://github.com/AppsFlyerSDK/flutter_appsflyer_sdk From 6481b39459dccbd10713810ca67a162d45d6b23a Mon Sep 17 00:00:00 2001 From: gabriel mandler Date: Tue, 20 Jun 2023 12:43:42 +0300 Subject: [PATCH 06/12] bug fix stop API for ios --- ios/Classes/AppsflyerSdkPlugin.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/Classes/AppsflyerSdkPlugin.m b/ios/Classes/AppsflyerSdkPlugin.m index c576a22..7ab2cfa 100644 --- a/ios/Classes/AppsflyerSdkPlugin.m +++ b/ios/Classes/AppsflyerSdkPlugin.m @@ -464,7 +464,7 @@ - (void)setCustomerUserId:(FlutterMethodCall*)call result:(FlutterResult)result{ } - (void)stop:(FlutterMethodCall*)call result:(FlutterResult)result{ - BOOL stop = call.arguments[@"isStopped"]; + BOOL stop = [[call.arguments objectForKey:@"isStopped"] boolValue]; [AppsFlyerLib shared].isStopped = stop; result(nil); } From 5a5a1d9a91299ffa7dda0d87ab764e0fb32ae02d Mon Sep 17 00:00:00 2001 From: gabriel mandler Date: Tue, 27 Jun 2023 18:02:36 +0300 Subject: [PATCH 07/12] fix null pointer exception bug --- .../appsflyersdk/AppsflyerSdkPlugin.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/android/src/main/java/com/appsflyer/appsflyersdk/AppsflyerSdkPlugin.java b/android/src/main/java/com/appsflyer/appsflyersdk/AppsflyerSdkPlugin.java index 389d048..ccc62fb 100644 --- a/android/src/main/java/com/appsflyer/appsflyersdk/AppsflyerSdkPlugin.java +++ b/android/src/main/java/com/appsflyer/appsflyersdk/AppsflyerSdkPlugin.java @@ -60,7 +60,8 @@ public class AppsflyerSdkPlugin implements MethodCallHandler, FlutterPlugin, Act private static String cachedOnAttributionFailure; private static String cachedOnConversionDataFail; private static DeepLinkResult cachedDeepLinkResult; - + private static ActivityPluginBinding activityPluginBinding; + final Handler uiThreadHandler = new Handler(Looper.getMainLooper()); private EventChannel mEventChannel; /** @@ -773,7 +774,9 @@ private void initSdk(MethodCall call, final MethodChannel.Result result) { AppsFlyerConversionListener gcdListener = null; DeepLinkListener udlListener = null; AppsFlyerLib instance = AppsFlyerLib.getInstance(); - + if(activity == null){ + activity = activityPluginBinding.getActivity(); + } String afDevKey = (String) call.argument(AppsFlyerConstants.AF_DEV_KEY); if (afDevKey == null || afDevKey.equals("")) { result.error(null, "AF Dev Key is empty", "AF dev key cannot be empty"); @@ -901,10 +904,11 @@ public void onDetachedFromEngine(FlutterPluginBinding binding) { @Override public void onAttachedToActivity(ActivityPluginBinding binding) { - activity = binding.getActivity(); - mIntent = binding.getActivity().getIntent(); - mApplication = binding.getActivity().getApplication(); - binding.addOnNewIntentListener(onNewIntentListener); + activityPluginBinding = binding; + activity = activityPluginBinding.getActivity(); + mIntent = activityPluginBinding.getActivity().getIntent(); + mApplication = activityPluginBinding.getActivity().getApplication(); + activityPluginBinding.addOnNewIntentListener(onNewIntentListener); } @Override From ab7d79ac769f7f4d17b173aab31b1d34dca906b3 Mon Sep 17 00:00:00 2001 From: gabriel mandler Date: Thu, 29 Jun 2023 16:30:28 +0300 Subject: [PATCH 08/12] update to android sdk v6.11.2 --- CHANGELOG.md | 4 +++- README.md | 2 +- android/build.gradle | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85f0704..5c359cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Versions ## 6.11.2 -- update to Android SDK to v6.11.1 and ios sdk v6.11.2 +- update to Android SDK to v6.11.2 +## 6.11.1 +- update to Android SDK to v6.11.1 ## 6.10.1 - update to Android SDK to v6.10.3 & iOS SDK to v6.10.1 ## 6.9.3 diff --git a/README.md b/README.md index f9c3fe7..ca8de42 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ ### This plugin is built for -- Android AppsFlyer SDK **v6.11.1** +- Android AppsFlyer SDK **v6.11.2** - iOS AppsFlyer SDK **v6.11.2** ## ❗❗ Breaking changes when updating to v6.x.x❗❗ diff --git a/android/build.gradle b/android/build.gradle index 83c5864..69c9a61 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -35,6 +35,6 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompat:appcompat:1.0.0' - implementation 'com.appsflyer:af-android-sdk:6.11.1' + implementation 'com.appsflyer:af-android-sdk:6.11.2' implementation 'com.android.installreferrer:installreferrer:2.1' } \ No newline at end of file From 57290b16cfc6d13ea767387e736e44186b8c5dcc Mon Sep 17 00:00:00 2001 From: gabriel mandler Date: Thu, 29 Jun 2023 16:34:22 +0300 Subject: [PATCH 09/12] update git ignore --- .gitignore | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitignore b/.gitignore index 2692b13..a585496 100644 --- a/.gitignore +++ b/.gitignore @@ -114,3 +114,9 @@ node_modules/ covBadgeGen.js coverage/ .env +example/windows/* +example/macos/* +example/linux/* +example/web/* +example/analysis_options.yaml + From d56e31bb38211112945c69802940823e6d30e8fa Mon Sep 17 00:00:00 2001 From: gabriel mandler Date: Tue, 11 Jul 2023 11:36:41 +0300 Subject: [PATCH 10/12] null pointer exception new fix --- .../appsflyersdk/AppsflyerSdkPlugin.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/android/src/main/java/com/appsflyer/appsflyersdk/AppsflyerSdkPlugin.java b/android/src/main/java/com/appsflyer/appsflyersdk/AppsflyerSdkPlugin.java index ccc62fb..bf96882 100644 --- a/android/src/main/java/com/appsflyer/appsflyersdk/AppsflyerSdkPlugin.java +++ b/android/src/main/java/com/appsflyer/appsflyersdk/AppsflyerSdkPlugin.java @@ -60,7 +60,6 @@ public class AppsflyerSdkPlugin implements MethodCallHandler, FlutterPlugin, Act private static String cachedOnAttributionFailure; private static String cachedOnConversionDataFail; private static DeepLinkResult cachedDeepLinkResult; - private static ActivityPluginBinding activityPluginBinding; final Handler uiThreadHandler = new Handler(Looper.getMainLooper()); private EventChannel mEventChannel; @@ -201,6 +200,10 @@ private void startListening(Object arguments, Result rawResult) { @Override public void onMethodCall(MethodCall call, Result result) { + if(activity == null){ + Log.d("AppsFlyer", "Activity isn't attached to the flutter engine"); + return; + } final String method = call.method; switch (method) { case "initSdk": @@ -774,9 +777,7 @@ private void initSdk(MethodCall call, final MethodChannel.Result result) { AppsFlyerConversionListener gcdListener = null; DeepLinkListener udlListener = null; AppsFlyerLib instance = AppsFlyerLib.getInstance(); - if(activity == null){ - activity = activityPluginBinding.getActivity(); - } + String afDevKey = (String) call.argument(AppsFlyerConstants.AF_DEV_KEY); if (afDevKey == null || afDevKey.equals("")) { result.error(null, "AF Dev Key is empty", "AF dev key cannot be empty"); @@ -904,11 +905,10 @@ public void onDetachedFromEngine(FlutterPluginBinding binding) { @Override public void onAttachedToActivity(ActivityPluginBinding binding) { - activityPluginBinding = binding; - activity = activityPluginBinding.getActivity(); - mIntent = activityPluginBinding.getActivity().getIntent(); - mApplication = activityPluginBinding.getActivity().getApplication(); - activityPluginBinding.addOnNewIntentListener(onNewIntentListener); + activity = binding.getActivity(); + mIntent = binding.getActivity().getIntent(); + mApplication = binding.getActivity().getApplication(); + binding.addOnNewIntentListener(onNewIntentListener); } @Override From 2bdde293bc88d7b631867155a0c5520eed424383 Mon Sep 17 00:00:00 2001 From: gabriel mandler Date: Tue, 11 Jul 2023 11:53:29 +0300 Subject: [PATCH 11/12] update version and change log --- CHANGELOG.md | 2 ++ pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c359cc..6a7dd47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,6 @@ # Versions +## 6.11.3 +- null pointer exception fix for android, push notification bug fix & ios sdk 6.11.2 ## 6.11.2 - update to Android SDK to v6.11.2 ## 6.11.1 diff --git a/pubspec.yaml b/pubspec.yaml index 9ebbf35..7807eb3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: appsflyer_sdk description: A Flutter plugin for AppsFlyer SDK. Supports iOS and Android. -version: 6.11.2 +version: 6.11.3 homepage: https://github.com/AppsFlyerSDK/flutter_appsflyer_sdk From dbcb57e528d6553d7e568be55f188b6dd8a78248 Mon Sep 17 00:00:00 2001 From: gabriel mandler Date: Tue, 11 Jul 2023 12:04:49 +0300 Subject: [PATCH 12/12] update appdelegate for att --- example/ios/Runner/AppDelegate.swift | 23 +++++++++++++++++++++++ example/ios/Runner/Info.plist | 10 ++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/example/ios/Runner/AppDelegate.swift b/example/ios/Runner/AppDelegate.swift index 70693e4..552f643 100644 --- a/example/ios/Runner/AppDelegate.swift +++ b/example/ios/Runner/AppDelegate.swift @@ -1,5 +1,7 @@ import UIKit import Flutter +import AppsFlyerLib +import AppTrackingTransparency @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { @@ -8,6 +10,27 @@ import Flutter didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { GeneratedPluginRegistrant.register(with: self) + AppsFlyerLib.shared().waitForATTUserAuthorization(timeoutInterval: 60) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) } + + override func applicationDidBecomeActive(_ application: UIApplication) { + if #available(iOS 14, *) { + ATTrackingManager.requestTrackingAuthorization { (status) in + switch status { + case .denied: + print("AuthorizationSatus is denied") + case .notDetermined: + print("AuthorizationSatus is notDetermined") + case .restricted: + print("AuthorizationSatus is restricted") + case .authorized: + print("AuthorizationSatus is authorized") + @unknown default: + fatalError("Invalid authorization status") + } + } + } + } } diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist index 7f55346..c508934 100644 --- a/example/ios/Runner/Info.plist +++ b/example/ios/Runner/Info.plist @@ -2,6 +2,8 @@ + CADisableMinimumFrameDurationOnPhone + CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName @@ -24,6 +26,10 @@ $(FLUTTER_BUILD_NUMBER) LSRequiresIPhoneOS + NSUserTrackingUsageDescription + hey + UIApplicationSupportsIndirectInputEvents + UILaunchStoryboardName LaunchScreen UIMainStoryboardFile @@ -43,9 +49,5 @@ UIViewControllerBasedStatusBarAppearance - CADisableMinimumFrameDurationOnPhone - - UIApplicationSupportsIndirectInputEvents -