From 15f677044613c06b100799d1dc6f47fb696d2a11 Mon Sep 17 00:00:00 2001 From: Nishant Kumar Date: Thu, 12 Oct 2023 15:47:58 +0530 Subject: [PATCH 1/7] - Supports CleverTap iOS SDK v5.2.1 - Adds new public API `setLocale(Locale locale)` to set user locale --- doc/Usage.md | 7 +++++++ example/ios/Podfile.lock | 16 ++++++++-------- example/lib/main.dart | 17 +++++++++++++++++ ios/Classes/CleverTapPlugin.m | 8 ++++++++ ios/clevertap_plugin.podspec | 2 +- lib/clevertap_plugin.dart | 7 +++++++ 6 files changed, 48 insertions(+), 9 deletions(-) diff --git a/doc/Usage.md b/doc/Usage.md index 7c629eb2..29e1d1f1 100644 --- a/doc/Usage.md +++ b/doc/Usage.md @@ -79,6 +79,13 @@ var lat = 19.07; var long = 72.87; CleverTapPlugin.setLocation(lat, long); ``` + +#### Set Locale of the user + +```Dart +Locale locale = Locale('en', 'IN'); +CleverTapPlugin.setLocale(locale); +``` ---- ## User Events diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 35af24fe..20e2a07b 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,13 +1,13 @@ PODS: - - CleverTap-iOS-SDK (5.2.0): + - CleverTap-iOS-SDK (5.2.1): - SDWebImage (~> 5.11) - clevertap_plugin (1.7.0): - - CleverTap-iOS-SDK (= 5.2.0) + - CleverTap-iOS-SDK (= 5.2.1) - Flutter - Flutter (1.0.0) - - SDWebImage (5.17.0): - - SDWebImage/Core (= 5.17.0) - - SDWebImage/Core (5.17.0) + - SDWebImage (5.18.3): + - SDWebImage/Core (= 5.18.3) + - SDWebImage/Core (5.18.3) DEPENDENCIES: - clevertap_plugin (from `.symlinks/plugins/clevertap_plugin/ios`) @@ -25,10 +25,10 @@ EXTERNAL SOURCES: :path: Flutter SPEC CHECKSUMS: - CleverTap-iOS-SDK: 6a38eea6d2f0c336fb142baadcca2cd8aafd2290 - clevertap_plugin: 3bdba39d5b71cf5d9c40eb8a077efd5e2423eb43 + CleverTap-iOS-SDK: 183b2f5c52ecfcb0d4cc97e0cdfcf080562026f3 + clevertap_plugin: 85d568eb8f142e6344445bac7eadab4766e1879b Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 - SDWebImage: 750adf017a315a280c60fde706ab1e552a3ae4e9 + SDWebImage: 96e0c18ef14010b7485210e92fac888587ebb958 PODFILE CHECKSUM: cf0c950f7e9a456b4e325f5b8fc0f98906a3705a diff --git a/example/lib/main.dart b/example/lib/main.dart index a0ac44a0..dae8db95 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1365,6 +1365,17 @@ class _MyAppState extends State { ), ), ), + Card( + color: Colors.grey.shade300, + child: Padding( + padding: const EdgeInsets.all(4.0), + child: ListTile( + title: Text("Set Locale"), + subtitle: Text("Use to set Locale of a user"), + onTap: setLocale, + ), + ), + ), ], )), ), @@ -1983,6 +1994,12 @@ class _MyAppState extends State { showToast("Location is set"); } + void setLocale() { + Locale locale = Locale('en', 'IN'); + CleverTapPlugin.setLocale(locale); + showToast("Locale is set"); + } + void getCTAttributionId() { CleverTapPlugin.profileGetCleverTapAttributionIdentifier() .then((attributionId) { diff --git a/ios/Classes/CleverTapPlugin.m b/ios/Classes/CleverTapPlugin.m index 46f929bf..a8486c5e 100644 --- a/ios/Classes/CleverTapPlugin.m +++ b/ios/Classes/CleverTapPlugin.m @@ -274,6 +274,8 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { [self onVariablesChanged:call withResult:result]; else if ([@"onValueChanged" isEqualToString:call.method]) [self onValueChanged:call withResult:result]; + else if ([@"setLocale" isEqualToString:call.method]) + [self setLocale:call withResult:result]; else result(FlutterMethodNotImplemented); } @@ -1365,4 +1367,10 @@ - (void)onValueChanged:(FlutterMethodCall *)call withResult:(FlutterResult)resul } } +- (void)setLocale:(FlutterMethodCall *)call withResult:(FlutterResult)result { + NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:call.arguments]; + [[CleverTap sharedInstance] setLocale:locale]; + result(nil); +} + @end diff --git a/ios/clevertap_plugin.podspec b/ios/clevertap_plugin.podspec index 9d11f773..c278b947 100644 --- a/ios/clevertap_plugin.podspec +++ b/ios/clevertap_plugin.podspec @@ -13,7 +13,7 @@ Pod::Spec.new do |s| s.source_files = 'Classes/**/*' s.public_header_files = 'Classes/**/*.h' s.dependency 'Flutter' - s.dependency 'CleverTap-iOS-SDK', '5.2.0' + s.dependency 'CleverTap-iOS-SDK', '5.2.1' s.ios.deployment_target = '9.0' end diff --git a/lib/clevertap_plugin.dart b/lib/clevertap_plugin.dart index 5848dcb7..2a8a648d 100644 --- a/lib/clevertap_plugin.dart +++ b/lib/clevertap_plugin.dart @@ -994,4 +994,11 @@ class CleverTapPlugin { cleverTapOnValueChangedHandlers.add(handler); _dartToNativeMethodChannel.invokeMethod('onValueChanged', {'name': name}); } + + ///Sets the user locale. + static Future setLocale(Locale locale) async { + String localeString = locale.toString(); + return await _dartToNativeMethodChannel.invokeMethod( + 'setLocale', localeString); + } } From 773af2faa657ddf6e979904ccf1518a0b6aacd2c Mon Sep 17 00:00:00 2001 From: Shivam Sharma Date: Wed, 18 Oct 2023 14:11:45 +0530 Subject: [PATCH 2/7] task(SDK-3354): update clevertap android sdk to v5.2.1 --- android/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/build.gradle b/android/build.gradle index 20355ead..76c3f06c 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -42,7 +42,7 @@ android { dependencies { testImplementation 'junit:junit:4.13.2' - api 'com.clevertap.android:clevertap-android-sdk:5.2.0' + api 'com.clevertap.android:clevertap-android-sdk:5.2.1' compileOnly 'androidx.fragment:fragment:1.3.6' compileOnly 'androidx.core:core:1.9.0' } From be2ff7ac523bd7dc22993bce138e7ec46e660460 Mon Sep 17 00:00:00 2001 From: Shivam Sharma Date: Wed, 18 Oct 2023 15:04:11 +0530 Subject: [PATCH 3/7] feat(SDK-3354): support setLocale() method call in platform specific plugin class --- .../clevertap_plugin/CleverTapPlugin.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/android/src/main/java/com/clevertap/clevertap_plugin/CleverTapPlugin.java b/android/src/main/java/com/clevertap/clevertap_plugin/CleverTapPlugin.java index 39d71b16..9bb45dff 100644 --- a/android/src/main/java/com/clevertap/clevertap_plugin/CleverTapPlugin.java +++ b/android/src/main/java/com/clevertap/clevertap_plugin/CleverTapPlugin.java @@ -240,6 +240,10 @@ public void onMethodCall(MethodCall call, @NonNull Result result) { } break; } + case "setLocale": { + setLocale(call, result); + break; + } // Push Methods case "setPushToken": { setPushToken(call, result, PushType.FCM); @@ -700,6 +704,16 @@ public void onMethodCall(MethodCall call, @NonNull Result result) { } + private void setLocale(MethodCall call, Result result) { + String locale = call.arguments(); + if (isCleverTapNotNull(cleverTapAPI)) { + cleverTapAPI.setLocale(locale); + result.success(null); + } else { + result.error(TAG, ERROR_MSG, null); + } + } + /************************************************** * Product Experience Remote Config methods starts *************************************************/ From 0f9a12a1dc4c96114d9b43e678f0b645e7f37ec0 Mon Sep 17 00:00:00 2001 From: Shivam Sharma Date: Thu, 19 Oct 2023 13:08:22 +0530 Subject: [PATCH 4/7] doc(SDK-3354): update changelog.md and usage.md --- CHANGELOG.md | 26 ++ doc/Usage.md | 908 ++++++++++++++------------------------------------- 2 files changed, 264 insertions(+), 670 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f632ef13..0b782a69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,31 @@ ## CHANGE LOG +### Version 1.9.1 *(20th October 2023)* +------------------------------------------- +**What's new** +* **[Android Platform]** + * Supports [CleverTap Android SDK v5.2.1](https://github.com/CleverTap/clevertap-android-sdk/blob/master/docs/CTCORECHANGELOG.md#version-521-october-12-2023). + * Adds Custom Proxy Domain functionality for Push Impressions and Events raised from CleverTap Android SDK. Please refer to [Usage.md](doc/Usage.md#integrate-custom-proxy-domain) file to read more on how to configure custom proxy domains in Android. + +* **[iOS Platform]** + * Supports [CleverTap iOS SDK v5.2.1](https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/5.2.1). + * Adds support to enable `NSFileProtectionComplete` to secure App’s document directory. + +* **[Android and iOS Platform]** + * Adds in-built support to send the default locale(i.e.language and country) data to the dashboard and exposed public API `CleverTapPlugin.setLocale(Locale locale)` to set the custom locale, for LP Parity. + * Adds support for Integration Debugger to view errors and events on the dashboard when the debugLevel is set to 3 using `CleverTapPlugin.setDebugLevel(3)`. + +**Changes** +* **[iOS Platform]** + * Updated logic to retrieve country code using NSLocale above iOS 16 as `CTCarrier` is deprecated above iOS 16 with no replacements, see [Apple Doc](https://developer.apple.com/documentation/coretelephony/ctcarrier). + * Updated logic to not send carrier name above iOS 16 in CTCarrier field. + +**Bug Fixes** +* **[iOS Platform]** + * Fixes a crash in iOS 17/Xcode 15 related to alert inapps. + * Fixes a failing `test_clevertap_instance_nscoding` test case. + + ### Version 1.9.0 *(29th August 2023)* ------------------------------------------- **What's new** diff --git a/doc/Usage.md b/doc/Usage.md index 29e1d1f1..667c7e29 100644 --- a/doc/Usage.md +++ b/doc/Usage.md @@ -1,671 +1,239 @@ -# Example Usage - -## User Profiles - -#### Update User Profile(Push Profile) - -```Dart -var stuff = ["bags", "shoes"]; -var profile = { - 'Name': 'John Wick', - 'Identity': '100', - 'DOB': '22-04-2000', - //Key always has to be "DOB" and format should always be dd-MM-yyyy - 'Email': 'john@gmail.com', - 'Phone': '14155551234', - 'props': 'property1', - 'stuff': stuff -}; -CleverTapPlugin.profileSet(profile); -``` - -#### Set Multi Values For Key - -```Dart -var values = ["value1", "value2"]; -CleverTapPlugin.profileSetMultiValues("props", values); -``` - -#### Remove Multi Value For Key - -```Dart -var values = ["value1", "value2"]; -CleverTapPlugin.profileRemoveMultiValues("props", values); -``` - -#### Add Multi Value For Key - -```Dart -var values = ["value1", "value2"]; -CleverTapPlugin.profileAddMultiValues("props", values); -``` - -#### Increment Value For Key - -```Dart -CleverTapPlugin.profileIncrementValue("score", value); -``` - -#### Decrement Value For Key - -```Dart -CleverTapPlugin.profileDecrementValue("score", value); -``` - -#### Create a User profile when user logs in (On User Login) - -```Dart -var stuff = ["bags", "shoes"]; -var profile = { - 'Name': 'Captain America', - 'Identity': '100', - 'Email': 'captain@america.com', - 'Phone': '+14155551234', - 'stuff': stuff -}; -CleverTapPlugin.onUserLogin(profile); -``` - -#### Get CleverTap Reference id - -```Dart -CleverTapPlugin.getCleverTapID().then((clevertapId) {}) -``` - -#### Set Location to User Profile - -```Dart -var lat = 19.07; -var long = 72.87; -CleverTapPlugin.setLocation(lat, long); -``` - -#### Set Locale of the user - -```Dart -Locale locale = Locale('en', 'IN'); -CleverTapPlugin.setLocale(locale); -``` ----- - -## User Events - -#### Record an event - -```Dart -var eventData = { - // Key: Value - 'first': 'partridge', - 'second': 'turtledoves' -}; -CleverTapPlugin.recordEvent("Flutter Event", eventData); -``` - -#### Record Charged event - -```Dart -var item1 = { - // Key: Value - 'name': 'thing1', - 'amount': '100' -}; -var item2 = { - // Key: Value - 'name': 'thing2', - 'amount': '100' -}; -var items = [item1, item2]; -var chargeDetails = { - // Key: Value - 'total': '200', - 'payment': 'cash' -}; -CleverTapPlugin.recordChargedEvent(chargeDetails, items); -``` -------- - -## In-App Notifications - -#### On In App Button Click - -```Dart -_clevertapPlugin.setCleverTapInAppNotificationButtonClickedHandler(inAppNotificationButtonClicked); - -void inAppNotificationButtonClicked(Map map) { - this.setState(() { - print("inAppNotificationButtonClicked called = ${map.toString()}"); - }); -} -``` - -#### On Dismissed - -```Dart -_clevertapPlugin.setCleverTapInAppNotificationDismissedHandler(inAppNotificationDismissed) - -void inAppNotificationDismissed(Map map) { - this.setState(() { - print("inAppNotificationDismissed called"); - }); -} -``` - -#### Suspend InApp Notifications - -```Dart -CleverTapPlugin.suspendInAppNotifications(); -``` - -#### Discard InApp Notifications - -```Dart -CleverTapPlugin.discardInAppNotifications(); -``` - -#### Resume InApp Notifications - -```Dart -CleverTapPlugin.resumeInAppNotifications(); -``` ------- - -## App Inbox - -#### Initialize App Inbox - -```Dart -CleverTapPlugin.initializeInbox(); -``` - -#### Show App Inbox - -```Dart -var styleConfig = { - 'noMessageTextColor': '#ff6600', - 'noMessageText': 'No message(s) to show.', - 'navBarTitle': 'App Inbox' -}; -CleverTapPlugin.showInbox(styleConfig); -``` - -#### App Inbox Item Click Callback - -```Dart -_clevertapPlugin.setCleverTapInboxNotificationMessageClickedHandler(inboxNotificationMessageClicked); - -void inboxNotificationMessageClicked(Map? data, int contentPageIndex, int buttonIndex) { - this.setState(() { - print("App Inbox item: ${data.toString()}"); - print("Content Page index: $contentPageIndex"); - print("Button index: $buttonIndex"); - }); -} -``` - -#### App Inbox Button Click Callback -```Dart -_clevertapPlugin.setCleverTapInboxNotificationButtonClickedHandler(inboxNotificationButtonClicked); - -void inboxNotificationButtonClicked(Map? map) { - this.setState(() { - print("inboxNotificationButtonClicked called = ${map.toString()}"); - }); -} -``` - -#### Dismiss the App Inbox -```Dart -CleverTapPlugin.dismissInbox(); -``` - -#### Get Total Inbox Message Count - -```Dart -int total = await CleverTapPlugin.getInboxMessageCount(); -print("Total count = " + total.toString()); -``` - -#### Get Total Inbox Unread Count - -```Dart -int unread = await CleverTapPlugin.getInboxMessageUnreadCount(); -print("Unread count = " + unread.toString()); - -``` - -#### Get All Inbox Messages - -```Dart -List messages = await CleverTapPlugin.getAllInboxMessages(); -``` - -#### Get All Inbox Unread Messages - -```Dart -List messages = await CleverTapPlugin.getUnreadInboxMessages(); -``` - -#### Get Inbox Message for the given message id - -```Dart -var messageForId = await CleverTapPlugin.getInboxMessageForId(messageId); -``` - -#### Delete Message for the given message id - -```Dart -await CleverTapPlugin.deleteInboxMessageForId(messageId); -``` - -#### Mark Message as Read for the given message id - -```Dart -var messageList = await CleverTapPlugin.getUnreadInboxMessages(); - if (messageList == null || messageList.length == 0) return; - Map itemFirst = messageList[0]; - if (Platform.isAndroid) { - await CleverTapPlugin.markReadInboxMessageForId(itemFirst["id"]); - } else if (Platform.isIOS) { - await CleverTapPlugin.markReadInboxMessageForId(itemFirst["_id"]); - } -``` - -#### Raise Notification Viewed event for Inbox Message. Message id should be a String - -```Dart -await CleverTapPlugin.pushInboxNotificationViewedEventForId(messageId); -``` - -#### Raise Notification Clicked event for Inbox Message. Message id should be a String - -```Dart -await CleverTapPlugin.pushInboxNotificationClickedEventForId(messageId); -``` -## Debugging - -#### Set Debug Level - -```Dart -CleverTapPlugin.setDebugLevel(3); -``` - -## Push Notifications - -#### **Handle Notification Click** -Register a `setCleverTapPushClickedPayloadReceivedHandler` handler to get a notification click callback along with the entire payload. - -```Dart -_clevertapPlugin.setCleverTapPushClickedPayloadReceivedHandler(pushClickedPayloadReceived); - -void pushClickedPayloadReceived(Map notificationPayload) { - print("pushClickedPayloadReceived called with notification payload: " + notificationPayload.toString()); - // You may perform UI operation like redirecting the user to a specific page based on custom key-value pairs - // passed in the notificationPayload. You may also perform non UI operation such as HTTP requests, IO with local storage etc. - handleNotificationClick(notificationPayload); -} -``` -> **Note:** -> -> Please note that the `pushClickedPayloadReceived` handler is triggered in Android platform only when the app is in the foreground or background states, and not when it has been terminated(killed). -> However, in the case of iOS platform, this handler is supported regardless of whether the app is in the foreground, background, or has been terminated (killed). - -#### **[Android Platform] Handle Notification Trampoline Restrictions to support `pushClickedPayloadReceived` handler in Android 12 and Above** -Due to [notification trampoline restrictions](https://developer.android.com/about/versions/12/behavior-changes-12#notification-trampolines), Android 12 and above do not directly support the `pushClickedPayloadReceived` callback. -Hence, apps need to add manual handling for Android 12 and above to inform the CleverTap SDK about the notification click and get the `pushClickedPayloadReceived` callback. - -Add the following code in the `onNewIntent()` method of the Launcher `FlutterActivity` class in android: -```kotlin -class MainActivity : FlutterActivity() { - -override fun onNewIntent(intent: Intent?) { - super.onNewIntent(intent) - - // On Android 12 and above, inform the notification click to get the pushClickedPayloadReceived callback on dart side. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - cleverTapDefaultInstance?.pushNotificationClickedEvent(intent!!.extras) - } - } -} -``` - -#### **[Android Platform] Handle Notification Clicks When the App Is Killed** -The CleverTap Plugin provides two ways to handle user interactions with notifications, depending on whether the app needs to perform UI or non-UI operations. - -##### **1. Perform UI impacting operation using `CleverTapPlugin.getAppLaunchNotification()`:** -The default behavior on Android is to launch the application if the application is terminated(killed). -Use `CleverTapPlugin.getAppLaunchNotification()` to get a Future containing a notification-payload of `Map` type if the application is opened from a terminated(killed) state. -Depending on the content of a notification-payload, you may perform UI operation like redirecting the user to a specific page. - -```Dart -class Application extends StatefulWidget { - @override - State createState() => _Application(); -} - -class _Application extends State { - void _handleKilledStateNotificationInteraction() async { - // Retrieve the notification-payload in a 'CleverTapAppLaunchNotification' class object - // which caused the application to open from a terminated state. - CleverTapAppLaunchNotification appLaunchNotification = await CleverTapPlugin - .getAppLaunchNotification(); - - if (appLaunchNotification.didNotificationLaunchApp) { - //App is launched from a notification click which was rendered by the CleverTap SDK. - Map notificationPayload = appLaunchNotification.payload!; - _handleDeeplink(); - } - } +## CHANGE LOG + +### Version 1.9.0 *(29th August 2023)* +------------------------------------------- +**What's new** +* **[Android Platform]** + * Supports [CleverTap Android SDK v5.2.1](https://github.com/CleverTap/clevertap-android-sdk/blob/master/docs/CTCORECHANGELOG.md#version-521-october-12-2023). + * Adds Custom Proxy Domain functionality for Push Impressions and Events raised from CleverTap Android SDK. Please refer to [Usage.md](doc/Usage.md#integrate-custom-proxy-domain) file to read more on how to configure custom proxy domains in Android. + +* **[iOS Platform]** + * Supports [CleverTap iOS SDK v5.2.1](https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/5.2.1). + * Adds support to enable `NSFileProtectionComplete` to secure App’s document directory. - void _handleDeeplink() { - // It is assumed that all notifications contain a data field with the key 'type' but you may also have - // a different key for deeplink handling. - var type = notificationPayload["type"]; - - if (type != null) { - print( - "_handleKilledStateNotificationInteraction => Type: $type"); - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - DeepLinkPage(type: type))); - } - } - - @override - void initState() { - super.initState(); - - // Run CleverTapPlugin.getAppLaunchNotification in an async function - // as initState() must not be async - if (Platform.isAndroid) { - _handleKilledStateNotificationInteraction(); - } - } - - @override - Widget build(BuildContext context) { - return Text("..."); - } -} -``` - -> **Note:** -> -> The notification needs to be generated by the CleverTap SDK to get the notification payload from the -> `CleverTapPlugin.getAppLaunchNotification()` API. - - -##### **2. Perform non-UI operation using `onKilledStateNotificationClicked` handler:** -There are two steps to setup the `onKilledStateNotificationClicked` handler: -1. Your `Application` class should extend the `CleverTapApplication` class instead of the `FlutterApplication` class. -2. Register the `onKilledStateNotificationClicked` handler to get a notification click callback along with the entire payload. When notification is clicked, an isolate is spawned (Android only) allowing you to handle notification click even when your application is not running. -There are a few things to keep in mind about your `onKilledStateNotificationClicked` handler: - - It must not be an anonymous function. - - It must be a top-level function (e.g. not a class method which requires initialization). - - When using Flutter version 3.3.0 or higher, the `onKilledStateNotificationClicked` handler must be annotated with `@pragma('vm:entry-point')` right above the function declaration (otherwise it may be removed during tree shaking for release mode). - -Add the following method to your `main.dart` file, right after the import statements, and outside any Widget class declaration, to process push notifications in the killed state via a Flutter background isolate: - -```Dart -@pragma('vm:entry-point') -void _onKilledStateNotificationClickedHandler(Map map) async { - print("Notification Payload received: " + map.toString()); -} - -void main() { - CleverTapPlugin.onKilledStateNotificationClicked(_onKilledStateNotificationClickedHandler); - runApp(MyApp()); -} -``` - -> **Note:** -> -> Since the `_onKilledStateNotificationClickedHandler` handler runs in its own isolate outside your applications context, it is not possible to update application state or execute any UI operation from the handler itself. -> You can, however, perform HTTP requests, IO operations with local storage etc. - -#### Creating Notification Channel - -```Dart -CleverTapPlugin.createNotificationChannel("fluttertest", "Flutter Test", "Flutter Test", 3, true); -``` - -#### Default Notification Channel -Starting from CleverTap Plugin v1.8.0 we have introduced a new feature that allows developers to define a default notification channel for their app. This feature provides flexibility in handling push notifications. -Please note that this is only supported for clevertap core notifications. Support for push templates will be released soon. To specify the default notification channel ID, you can add the following metadata in your app's manifest file: - -```XML - -``` - -By including this metadata, you can define a specific notification channel that CleverTap will use if the channel provided in push payload is not registered by your app. This ensures that push notifications are displayed consistently even if the app's notification channels are not set up. - -In case the SDK does not find the default channel ID specified in the manifest, it will automatically fallback to using a default channel called "Miscellaneous". This ensures that push notifications are still delivered, even if no specific default channel is specified in the manifest. - -This enhancement provides developers with greater control over the default notification channel used by CleverTap for push notifications, ensuring a seamless and customizable user experience. - -#### Delete Notification Channel - -```Dart -CleverTapPlugin.deleteNotificationChannel(“channelId”); -``` - -#### Creating a group notification channel - -```Dart -CleverTapPlugin.createNotificationChannelGroup(“groupId”, “groupName”); -``` - -#### Delete a group notification channel - -```Dart -CleverTapPlugin.deleteNotificationChannelGroup(“channelId”); -``` - -#### Registering Fcm, Baidu, Xiaomi, Huawei Token - -```Dart -CleverTapPlugin.setPushToken(“value”); -CleverTapPlugin.setBaiduPushToken(“value”); -CleverTapPlugin.setXiaomiPushToken(“value”); -CleverTapPlugin.setHuaweiPushToken(“value”); -``` - - #### Create Notification - -```Dart -CleverTapPlugin.createNotification(data); -``` - ------- - -## Custom Push Amplification - -#### Process Push Notification - -```Dart - CleverTapPlugin.processPushNotification(data); -``` - ---------- - -## Native Display - -#### On Display Units Loaded - -```Dart -void onDisplayUnitsLoaded(List displayUnits) { - this.setState(() { - print("Display Units = " + displayUnits.toString()); - }); -} -``` - -#### Get All Display Units - -```Dart -void onDisplayUnitsLoaded(List displayUnits) { - this.setState(() async { - List displayUnits = await CleverTapPlugin.getAllDisplayUnits(); - print("Display Units = " + displayUnits.toString()); - }); -} -``` - -#### Display unit viewed event for ID - -```Dart -CleverTapPlugin.pushDisplayUnitViewedEvent(“unitId”); -``` -#### Display unit clicked event for ID - -```Dart -CleverTapPlugin.pushDisplayUnitClickedEvent(“unitId”); -``` - -## Product Config - -#### Set Product Configuration to default - -```Dart -void productConfigInitialized() { - print("Product Config Initialized"); - this.setState(() async { - await CleverTapPlugin.fetch(); - }); -} -``` - -#### Fetching product configs - -```Dart -void fetch() { - CleverTapPlugin.fetch(); - // CleverTapPlugin.fetchWithMinimumIntervalInSeconds(0); -} -``` - -#### Activate the most recently fetched product config - -```Dart -void activate() { - CleverTapPlugin.activate(); -} -``` - -#### Fetch And Activate product config - -```Dart -void fetchAndActivate() { - CleverTapPlugin.fetchAndActivate(); - } -``` - -#### Fetch Minimum Time Interval - -```Dart -CleverTapPlugin.setMinimumFetchIntervalInSeconds(interval); -``` - -#### Get Boolean key - -```Dart - CleverTapPlugin.getProductConfigBoolean(“key”); -``` - -#### Get last fetched timestamp in millis - -```Dart -CleverTapPlugin.getLastFetchTimeStampInMillis(); -``` - -## Feature Flag - -#### Get Feature Flag - -```Dart -void featureFlagsUpdated() { - this.setState(() async { - bool booleanVar = await CleverTapPlugin.getFeatureFlag("BoolKey", false); - }); -} -``` - -## App Personalization - -#### Enable Personalization - -```Dart -CleverTapPlugin.enablePersonalization(); -``` - -#### Disable Personalization - -```Dart -CleverTapPlugin.disablePersonalization(); -``` - -## Attributions - -#### Push Install Refferer - -```Dart -CleverTapPlugin.pushInstallReferrer("source", "medium", "campaign"); -``` - -## GDPR - -#### Set Opt Out - -```Dart -CleverTapPlugin.setOptOut(false); ///Will opt in the user to send data to CleverTap -CleverTapPlugin.setOptOut(true); ///Will opt out the user to send data to CleverTap -``` - -#### Enable Device Networking Info Reporting - -```Dart -// Will opt out the user to send Device Network data to CleverTap -CleverTapPlugin.enableDeviceNetworkInfoReporting(false); -// Will opt in the user to send Device Network data to CleverTap -CleverTapPlugin.enableDeviceNetworkInfoReporting(true); -``` - -## Set Offline - -```Dart -// Will set the user online -CleverTapPlugin.setOffline(false); -// Will set the user offline -CleverTapPlugin.setOffline(true); -``` - ------------ - -## Push primer for notification Permission (Android and iOS) -Follow the [Push Primer integration doc](PushPrimer.md). - -## Encryption of PII data (Android and iOS) -PII data is stored across the SDK and could be sensitive information. From CleverTap Flutter SDK v1.9.0 onwards, you can enable encryption for PII data wiz. Email, Identity, Name and Phone. - -Currently 2 levels of encryption are supported i.e None(0) and Medium(1). Encryption level is None by default. -**None** - All stored data is in plaintext -**Medium** - PII data is encrypted completely. - -#### Android -Add encryption level in the `AndroidManifest.xml` as following: -```XML - -``` -#### iOS -Add the `CleverTapEncryptionLevel` String key to `info.plist` file where value 1 means Medium and 0 means None. Encryption Level will be None if any other value is provided. - - -### For more information, - - - [See Example Application Dart interface](/example/lib/main.dart) - - [See CleverTap Dart interface](/lib/clevertap_plugin.dart) - - +* **[Android and iOS Platform]** + * Adds in-built support to send the default locale(i.e.language and country) data to the dashboard and exposed public API `CleverTapPlugin.setLocale(Locale locale)` to set the custom locale, for LP Parity. + * Adds support for Integration Debugger to view errors and events on the dashboard when the debugLevel is set to 3 using `CleverTapPlugin.setDebugLevel(3)`. + +**Changes** +* **[iOS Platform]** + * Updated logic to retrieve country code using NSLocale above iOS 16 as `CTCarrier` is deprecated above iOS 16 with no replacements, see [apple doc](https://developer.apple.com/documentation/coretelephony/ctcarrier). + * Updated logic to not send carrier name above iOS 16 in CTCarrier field. + +**Bug Fixes** +* **[iOS Platform]** + * Fixes a crash in iOS 17/Xcode 15 related to alert inapps. + * Fixes a failing `test_clevertap_instance_nscoding` test case. + + +### Version 1.9.0 *(29th August 2023)* +------------------------------------------- +**What's new** +* **[Android Platform]** + * Supports [CleverTap Android SDK v5.2.0](https://github.com/CleverTap/clevertap-android-sdk/blob/master/docs/CTCORECHANGELOG.md#version-520-august-10-2023). + +* **[iOS Platform]** + * Supports [CleverTap iOS SDK v5.2.0](https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/5.2.0). + +* **[Android and iOS Platform]** + * Adds support for encryption of PII data wiz. Email, Identity, Name and Phone. Please refer to [Usage.md](https://github.com/CleverTap/clevertap-flutter/blob/master/doc/Usage.md#encryption-of-pii-data) file to read more on how to enable/disable encryption of PII data. + * Adds support for custom KV pairs common to all inbox messages in App Inbox. + +**Bug Fixes** +* **[Android Platform]** + * Fixes [#393](https://github.com/CleverTap/clevertap-android-sdk/issues/393) - push permission flow crash when context in CoreMetadata is null. + * Fixes a bug where addMultiValueForKey and addMultiValuesForKey were overwriting the current values of the user properties instead of appending it. + +### Version 1.8.1 *(31st July 2023)* +------------------------------------------- +**What's new** +* Supports [CleverTap iOS SDK v5.1.2](https://github.com/CleverTap/clevertap-ios-sdk/blob/master/CHANGELOG.md#version-512-july-28-2023) + +**Bug Fixes** +* **[iOS Platform]** + * Fixed a bug where the App Inbox would appear empty. + +### Version 1.8.0 *(17th July 2023)* +------------------------------------------- +**What's new** +* Supports [CleverTap Android SDK v5.1.0](https://github.com/CleverTap/clevertap-android-sdk/blob/master/docs/CTCORECHANGELOG.md#version-510-june-28-2023) +* Supports [CleverTap iOS SDK v5.1.1](https://github.com/CleverTap/clevertap-ios-sdk/blob/master/CHANGELOG.md#version-511-july-13-2023) +* ***Note: RenderMax Push SDK functionality is now supported directly within the CleverTap Core SDK***. Please remove the integrated *RenderMax SDK* before you upgrade to CleverTap Flutter SDK for this 1.8.0 version. +* Adds support for **notification click handling when the app is terminated or killed**. The CleverTap plugin provides two ways to handle user interactions with notifications, depending on whether the app needs to perform UI or non-UI operations. + * Use `CleverTapPlugin.getAppLaunchNotification()` to perform UI impacting operation like redirecting the user to a specific page. + * Use `CleverTapPlugin.onKilledStateNotificationClicked(_onKilledStateNotificationClickedHandler)` to perform non-UI operation like performing HTTP requests, IO operations with local storage etc. + Please refer to the [Notification Click Handling](https://github.com/CleverTap/clevertap-flutter/blob/master/doc/Usage.md#handle-notification-click) to learn more about properly handling notification clicks. +* ***[Android Platform]:*** Adds support for developer defined default notification channel. Please refer to the [Usage.md](https://github.com/CleverTap/clevertap-flutter/blob/master/doc/Usage.md#default-notification-channel) file to read more on how to setup default channel in your app.Also please note that this is only supported for clevertap core notifications. Support for push templates will be released soon. + +**Changes** +* The `CleverTapPlugin.createNotification(data)` API now supports rendering push template notifications and handling VoIP push for the SignedCall SDK. + +**Bug Fixes** +* **[iOS Platform]** + * Fixed Cocoapods generated duplicate UUIDs warnings. + * Mitigates potential App Inbox errors. +* **[Android Platform]** + * Fixes [#428](https://github.com/CleverTap/clevertap-android-sdk/issues/428) - Race-condition when detecting if an in-app message should show. + * Fixes Push primer alert dialog freeze behavior, which became unresponsive when clicked outside the window. + +### Version 1.7.0 *(8th June 2023)* +------------------------------------------- +**What's new** +* Adds support for **Remote Config Variables**. Please refer to the [Remote Config Variables doc](https://github.com/CleverTap/clevertap-flutter/blob/master/doc/Variables.md) to read more on how to integrate this to your app. +* Adds new API `dismissInbox()` to dismiss the App Inbox screen. +* Adds new APIs, `markReadInboxMessagesForIDs(List)` and `deleteInboxMessagesForIDs(List)` to mark read and delete an array of Inbox Messages respectively. +* Supports [CleverTap Android SDK v5.0.0](https://github.com/CleverTap/clevertap-android-sdk/blob/master/docs/CTCORECHANGELOG.md#version-500-may-5-2023) +* Supports [CleverTap iOS SDK v5.0.1](https://github.com/CleverTap/clevertap-ios-sdk/blob/master/CHANGELOG.md#version-501-may-17-2023) + +**API Changes** + +***Deprecated:*** The following methods and classes related to Product Config and Feature Flags have been marked as deprecated in this release, instead use new Remote Config Variables feature. These methods and classes will be removed in the future versions with prior notice. + +* Product config + * `setDefaultsMap` + * `fetch` + * `activate` + * `fetchAndActivate` + * `setMinimumFetchIntervalInSeconds` + * `resetProductConfig` + * `getProductConfigString` + * `getProductConfigBoolean` + * `getNumber` + * `getLastFetchTimeStampInMillis` + +* Feature flags + * `getFeatureFlag` + +**Breaking Change** +* Streamlines the payload for various callbacks across Android and iOS platform. Refer [doc](https://github.com/CleverTap/clevertap-flutter/blob/master/doc/callbackPayloadFormat.md) for detailed changes. +* ***[Android and iOS platforms] Signature change of the `CleverTapInboxNotificationMessageClickedHandler` callback]***: + It is changed from `CleverTapInboxNotificationMessageClickedHandler(Map? data)` to `CleverTapInboxNotificationMessageClickedHandler(Map? data, int contentPageIndex, int buttonIndex)`. The `contentPageIndex` corresponds to the page index of the content, which ranges from 0 to the total number of pages for carousel templates. For non-carousel templates, the `contentPageIndex` value is always 0, as they only have one page of content. The `buttonIndex` corresponds to the the App Inbox button clicked (0, 1, or 2). A value of -1 in `buttonIndex` field indicates the entire App Inbox Item is clicked. + +**Changes** +- ***[Android Platform] Behavioral change of CleverTap.CleverTapInboxMessageTapped listener:*** Previously, the callback was raised when the App Inbox item is clicked. Now, it is also raised when the App Inbox button is clicked. It matches the behavior in iOS platform. + +**Bug Fixes** +* Fixes a bug where App Inbox was not respecting the App Inbox background color when no tabs are provided. +* Fixes the non-EU retry mechanism bug. +* Fixes the data handling exception that is thrown by the `processPushNotification(dynamic data)` API. + +### Version 1.6.1 (April 4, 2023) +* Fixed compilation errors in Xcode 14.3+ in iOS. +* Streamlined the argument of `onDisplayUnitsLoaded` callback method in iOS to directly pass display unit array. +* Supports [CleverTap iOS SDK v4.2.2](https://github.com/CleverTap/clevertap-ios-sdk/blob/master/CHANGELOG.md#version-422-april-03-2023) + +### Version 1.6.0 (February 14, 2023) +* Adds below new public APIs to support [CleverTap Android SDK v4.7.4](https://github.com/CleverTap/clevertap-android-sdk/blob/master/docs/CTCORECHANGELOG.md#version-474-january-27-2023) and [CleverTap iOS SDK v4.2.0](https://github.com/CleverTap/clevertap-ios-sdk/blob/master/CHANGELOG.md#version-420-december-13-2022) + - `getPushNotificationPermissionStatus()`, `promptPushPrimer(object)`, `promptForPushNotification(boolean)` +* Adds push permission callback method `setCleverTapPushPermissionResponseReceivedHandler` which returns true/false after user allows/denies the notification permission. +* Adds `setCleverTapInAppNotificationShowHandler` to handle InApp notification shown - Only for Android. +* Streamlined the format of native display payload across Android and iOS. +* Fixes the FCM Plugin's [onBackgroundMessage handler bug](https://github.com/CleverTap/clevertap-flutter/commit/8db6f34eec83e7f14990359f88c65a50e966acb3) which was breaking the CleverTap Plugin's platform channel for sending method calls from Android. + +### Version 1.5.6 (April 5, 2023) +#### Added +* Supports [CleverTap Android SDK v4.6.9](https://github.com/CleverTap/clevertap-android-sdk/blob/master/docs/CTCORECHANGELOG.md#version-469-march-31-2023) +* Supports [CleverTap iOS SDK v4.2.2](https://github.com/CleverTap/clevertap-ios-sdk/blob/master/CHANGELOG.md#version-422-april-03-2023) +* Adds the new public API `dismissInbox()` to dismiss the App Inbox. +* **Note**: This release is being done for Android 12 targeted users. + +#### Changed +* **[Breaking change to the signature of the `CleverTapInboxNotificationMessageClickedHandler` callback]**: + It is changed from `CleverTapInboxNotificationMessageClickedHandler(Map? data)` to `CleverTapInboxNotificationMessageClickedHandler(Map? data, int contentPageIndex, int buttonIndex)`. The `contentPageIndex` corresponds to the page index of the content, which ranges from 0 to the total number of pages for carousel templates. For non-carousel templates, the `contentPageIndex` value is always 0, as they only have one page of content. The `buttonIndex` corresponds to the the App Inbox button clicked (0, 1, or 2). A value of -1 in `buttonIndex` field indicates the entire App Inbox Item is clicked. +* **[Behavioral change of the `CleverTapInboxNotificationMessageClickedHandler` callback]**: + Previously, the callback was raised when the App Inbox Item is clicked. Now, it is also raised when the App Inbox button is clicked besides the item click. +* **[Native Display parity changes]**: + - Streamlines the format of native display payload across Android and iOS. + - Streamlines the argument of `onDisplayUnitsLoaded` callback method in iOS to pass the list of displayUnits. + +#### Fixed +* Fixes the FCM Plugin's [onBackgroundMessage handler bug](https://github.com/CleverTap/clevertap-flutter/commit/8db6f34eec83e7f14990359f88c65a50e966acb3) which was breaking the CleverTap Plugin's platform channel for sending method calls from Android to Dart platform. +* Fixes the Xcode 14.3+ compilation errors in iOS. + +### Version 1.5.5 (January 23, 2023) +* Adds fix for closing App Inbox controller when deeplink is present in iOS. +* Supports [add-to-app](https://docs.flutter.dev/development/add-to-app) feature for Android platform to embed the CleverTap plugin in a flutter module. + +### Version 1.5.4 (November 4, 2022) +* Supports [CleverTap iOS SDK v4.1.4](https://github.com/CleverTap/clevertap-ios-sdk/blob/master/CHANGELOG.md#version-414-october-24-2022) + +### Version 1.5.3 (October 28, 2022) +* Fixes incorrect API being called in `profileAddMultiValues` in iOS. + +### Version 1.5.2 (October 7, 2022) +* Supports [CleverTap Android SDK v4.6.3](https://github.com/CleverTap/clevertap-android-sdk/releases/tag/corev4.6.3) +* [Breaking Change] `setXiaomiPushToken` API has been modified to accept region to comply with new Mi Push Region changes. Refer to [CleverTap Xiaomi Push SDK v1.5.0 Changelog](https://github.com/CleverTap/clevertap-android-sdk/blob/master/docs/CTXIAOMIPUSHCHANGELOG.md) +* Supports [CleverTap iOS SDK v4.1.2](https://github.com/CleverTap/clevertap-ios-sdk/blob/master/CHANGELOG.md#version-412-september-16-2022) + +### Version 1.5.1 (April 7, 2022) +* Adds the missing getter methods for Product Config in iOS. + +### Version 1.5.0 (March 8, 2022) +* Supports [CleverTap Android SDK v4.4.0](https://github.com/CleverTap/clevertap-android-sdk/releases/tag/core-v4.4.0) +* Supports [CleverTap iOS SDK v4.0.0](https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/4.0.0) + +### Version 1.4.0 (December 1, 2021) +* Adds fix for NPE [#61](https://github.com/CleverTap/clevertap-flutter/issues/61) +* Adds `result.success(null)` for all method calls [#81](https://github.com/CleverTap/clevertap-flutter/issues/81) +* Supports [CleverTap Android SDK v4.3.1](https://github.com/CleverTap/clevertap-android-sdk/releases/tag/core-v4.3.1) + +### Version 1.3.0 (September 13, 2021) +* Adds public methods for suspending, discarding & resuming InApp Notifications +* Adds public methods to increment/decrement values set via User properties +* Deprecates `profileGetCleverTapID()` and `profileGetCleverTapAttributionIdentifier()` methods +* Adds a new public method `getCleverTapID()` as an alternative to above deprecated methods +* Supports [CleverTap iOS SDK v3.10.0](https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/3.10.0) + +### Version 1.2.3 (July 20, 2021) +* Supports [CleverTap Android SDK v4.2.0](https://github.com/CleverTap/clevertap-android-sdk/releases/tag/core-v4.2.0) +* Adds fix for NPE [#58](https://github.com/CleverTap/clevertap-flutter/issues/58) +* Adds fix for `recordScreen` NPE [#54](https://github.com/CleverTap/clevertap-flutter/issues/54) + +### Version 1.2.2 (May 21, 2021) +* Supports [CleverTap Android SDK v4.1.1](https://github.com/CleverTap/clevertap-android-sdk/releases/tag/core-v4.1.1) +* Supports [CleverTap iOS SDK v3.9.4](https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/3.9.4) +* Removes Product A/B Testing (Dynamic Variables) code +* Removes `profileSetGraphUser` method +* Adds `pushNotificationViewedEvent` and `pushNotificationClickedEvent` + +### Version 1.2.1 (April 23, 2021) +* Update and Freeze [CleverTap Plugin Podspec](https://github.com/CleverTap/clevertap-flutter/blob/master/ios/clevertap_plugin.podspec) to a specific version of a CleverTap iOS SDK + +### Version 1.2.0 (October 13, 2020) +* Supports [CleverTap Android SDK v4.0.0](https://github.com/CleverTap/clevertap-android-sdk/releases/tag/core-v4.0.0) +* Supports [CleverTap iOS SDK v3.9.1](https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/3.9.1) + +### Version 1.1.4 (August 4, 2020) +* Supports [CleverTap Android SDK v3.8.2](https://github.com/CleverTap/clevertap-android-sdk/releases/tag/3.8.2) + +### Version 1.1.3 (July 17, 2020) +* Use v1.1.4 +* Adds a callback to provide Push Notifications custom key-value pairs +* Supports CleverTap [Android](https://github.com/CleverTap/clevertap-android-sdk/releases/tag/3.8.1) and [iOS](https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/3.8.1) SDK v3.8.1 +* Sample App Updated + +### Version 1.1.2 (May 20, 2020) +* Use v1.1.4 +* Adds support for Product Config and Feature Flags +* Adds support for Custom Handling Push Amplification Campaigns +* Supports CleverTap [Android](https://github.com/CleverTap/clevertap-android-sdk/releases/tag/3.8.0) and [iOS](https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/3.8.0) SDK v3.8.0 + +### Version 1.1.1 (March 30, 2020) +* Use v1.1.4 +* Adds support for Custom App Inbox +* Adds support for InApp/Inbox button click listeners +* Adds support for Notification Clicked/Viewed for App Inbox +* Adds support for passing Xiaomi/Baidu tokens. +* Supports [CleverTap Android SDK v3.7.2](https://github.com/CleverTap/clevertap-android-sdk/releases/tag/3.7.2) +* Supports [CleverTap iOS SDK v3.7.3](https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/3.7.3) + +### Version 1.1.0 (February 27, 2020) +* Adds support for Dynamic Variables & Native Display +* Adds support for Google Play Install Referrer Library v1.0 +* Supports CleverTap Android SDK v3.6.4 +* Supports CleverTap iOS SDK v3.7.2 + +### Version 1.0.0 (January 20, 2020) +* Initial Release. +* Supports CleverTap Android SDK v3.6.1 +* Supports CleverTap iOS SDK v3.7.2 From cf109a414874cc1ceb9ca92c4dc44d691f2b3704 Mon Sep 17 00:00:00 2001 From: Shivam Sharma Date: Thu, 19 Oct 2023 13:11:54 +0530 Subject: [PATCH 5/7] chore(SDK): bump plugin version to v1.9.1 --- android/build.gradle | 2 +- doc/Usage.md | 941 ++++++++++++++++++++++++++++++++----------- pubspec.yaml | 2 +- 3 files changed, 705 insertions(+), 240 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 76c3f06c..c7367bf2 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,5 +1,5 @@ group 'com.clevertap.clevertap_plugin' -version '1.9.0' +version '1.9.1' buildscript { repositories { diff --git a/doc/Usage.md b/doc/Usage.md index 667c7e29..5a258a96 100644 --- a/doc/Usage.md +++ b/doc/Usage.md @@ -1,239 +1,704 @@ -## CHANGE LOG - -### Version 1.9.0 *(29th August 2023)* -------------------------------------------- -**What's new** -* **[Android Platform]** - * Supports [CleverTap Android SDK v5.2.1](https://github.com/CleverTap/clevertap-android-sdk/blob/master/docs/CTCORECHANGELOG.md#version-521-october-12-2023). - * Adds Custom Proxy Domain functionality for Push Impressions and Events raised from CleverTap Android SDK. Please refer to [Usage.md](doc/Usage.md#integrate-custom-proxy-domain) file to read more on how to configure custom proxy domains in Android. - -* **[iOS Platform]** - * Supports [CleverTap iOS SDK v5.2.1](https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/5.2.1). - * Adds support to enable `NSFileProtectionComplete` to secure App’s document directory. +# Example Usage + +## User Profiles + +#### Update User Profile(Push Profile) + +```Dart +var stuff = ["bags", "shoes"]; +var profile = { + 'Name': 'John Wick', + 'Identity': '100', + 'DOB': '22-04-2000', + //Key always has to be "DOB" and format should always be dd-MM-yyyy + 'Email': 'john@gmail.com', + 'Phone': '14155551234', + 'props': 'property1', + 'stuff': stuff +}; +CleverTapPlugin.profileSet(profile); +``` + +#### Set Multi Values For Key + +```Dart +var values = ["value1", "value2"]; +CleverTapPlugin.profileSetMultiValues("props", values); +``` + +#### Remove Multi Value For Key + +```Dart +var values = ["value1", "value2"]; +CleverTapPlugin.profileRemoveMultiValues("props", values); +``` + +#### Add Multi Value For Key + +```Dart +var values = ["value1", "value2"]; +CleverTapPlugin.profileAddMultiValues("props", values); +``` + +#### Increment Value For Key + +```Dart +CleverTapPlugin.profileIncrementValue("score", value); +``` + +#### Decrement Value For Key + +```Dart +CleverTapPlugin.profileDecrementValue("score", value); +``` + +#### Create a User profile when user logs in (On User Login) + +```Dart +var stuff = ["bags", "shoes"]; +var profile = { + 'Name': 'Captain America', + 'Identity': '100', + 'Email': 'captain@america.com', + 'Phone': '+14155551234', + 'stuff': stuff +}; +CleverTapPlugin.onUserLogin(profile); +``` + +#### Get CleverTap Reference id + +```Dart +CleverTapPlugin.getCleverTapID().then((clevertapId) {}) +``` + +#### Set Location to User Profile + +```Dart +var lat = 19.07; +var long = 72.87; +CleverTapPlugin.setLocation(lat, long); +``` + +#### Set Locale of the user + +```Dart +Locale locale = Locale('en', 'IN'); +CleverTapPlugin.setLocale(locale); +``` +---- + +## Integrate Custom Proxy Domain +The custom proxy domain feature allows to proxy all events raised from the CleverTap SDK through your required domain, +ideal for handling or relaying CleverTap events and Push Impression events with your application server. +Refer following steps to configure the custom proxy domain(s) in the manifest file: + +#### [Android Platform] Configure Custom Proxy Domain(s) using Manifest file +1. Add your CleverTap Account credentials in the Manifest file against the `CLEVERTAP_ACCOUNT_ID` and `CLEVERTAP_TOKEN` keys. +2. Add the **CLEVERTAP_PROXY_DOMAIN** key with the proxy domain value for handling events through the custom proxy domain. +3. Add the **CLEVERTAP_SPIKY_PROXY_DOMAIN** key with proxy domain value for handling push impression events. + +```xml + + + + +``` +#### [iOS Platform] Configure Custom Proxy Domain(s) using `CleverTap.autoIntegrate()` API +1. Add your CleverTap Account credentials in the *Info.plist* file against the `CleverTapAccountID` and `CleverTapToken` keys. +2. Add the `CleverTapProxyDomain` key with the proxy domain value for handling events through the custom proxy domain e.g., *analytics.sdktesting.xyz*. +3. Add the `CleverTapSpikyProxyDomain` key with proxy domain value for handling push impression events e.g., *spiky-analytics.sdktesting.xyz*. +4. Import the CleverTap SDK in your *AppDelegate* file and call the following method in the `didFinishLaunchingWithOptions:` method. + ``` swift + CleverTap.autoIntegrate() + ``` + +## User Events + +#### Record an event + +```Dart +var eventData = { + // Key: Value + 'first': 'partridge', + 'second': 'turtledoves' +}; +CleverTapPlugin.recordEvent("Flutter Event", eventData); +``` + +#### Record Charged event + +```Dart +var item1 = { + // Key: Value + 'name': 'thing1', + 'amount': '100' +}; +var item2 = { + // Key: Value + 'name': 'thing2', + 'amount': '100' +}; +var items = [item1, item2]; +var chargeDetails = { + // Key: Value + 'total': '200', + 'payment': 'cash' +}; +CleverTapPlugin.recordChargedEvent(chargeDetails, items); +``` +------- + +## In-App Notifications + +#### On In App Button Click + +```Dart +_clevertapPlugin.setCleverTapInAppNotificationButtonClickedHandler(inAppNotificationButtonClicked); + +void inAppNotificationButtonClicked(Map map) { + this.setState(() { + print("inAppNotificationButtonClicked called = ${map.toString()}"); + }); +} +``` + +#### On Dismissed + +```Dart +_clevertapPlugin.setCleverTapInAppNotificationDismissedHandler(inAppNotificationDismissed) + +void inAppNotificationDismissed(Map map) { + this.setState(() { + print("inAppNotificationDismissed called"); + }); +} +``` + +#### Suspend InApp Notifications + +```Dart +CleverTapPlugin.suspendInAppNotifications(); +``` + +#### Discard InApp Notifications + +```Dart +CleverTapPlugin.discardInAppNotifications(); +``` + +#### Resume InApp Notifications + +```Dart +CleverTapPlugin.resumeInAppNotifications(); +``` +------ + +## App Inbox + +#### Initialize App Inbox + +```Dart +CleverTapPlugin.initializeInbox(); +``` + +#### Show App Inbox + +```Dart +var styleConfig = { + 'noMessageTextColor': '#ff6600', + 'noMessageText': 'No message(s) to show.', + 'navBarTitle': 'App Inbox' +}; +CleverTapPlugin.showInbox(styleConfig); +``` + +#### App Inbox Item Click Callback + +```Dart +_clevertapPlugin.setCleverTapInboxNotificationMessageClickedHandler(inboxNotificationMessageClicked); + +void inboxNotificationMessageClicked(Map? data, int contentPageIndex, int buttonIndex) { + this.setState(() { + print("App Inbox item: ${data.toString()}"); + print("Content Page index: $contentPageIndex"); + print("Button index: $buttonIndex"); + }); +} +``` + +#### App Inbox Button Click Callback +```Dart +_clevertapPlugin.setCleverTapInboxNotificationButtonClickedHandler(inboxNotificationButtonClicked); + +void inboxNotificationButtonClicked(Map? map) { + this.setState(() { + print("inboxNotificationButtonClicked called = ${map.toString()}"); + }); +} +``` + +#### Dismiss the App Inbox +```Dart +CleverTapPlugin.dismissInbox(); +``` + +#### Get Total Inbox Message Count + +```Dart +int total = await CleverTapPlugin.getInboxMessageCount(); +print("Total count = " + total.toString()); +``` + +#### Get Total Inbox Unread Count + +```Dart +int unread = await CleverTapPlugin.getInboxMessageUnreadCount(); +print("Unread count = " + unread.toString()); + +``` + +#### Get All Inbox Messages + +```Dart +List messages = await CleverTapPlugin.getAllInboxMessages(); +``` + +#### Get All Inbox Unread Messages + +```Dart +List messages = await CleverTapPlugin.getUnreadInboxMessages(); +``` + +#### Get Inbox Message for the given message id + +```Dart +var messageForId = await CleverTapPlugin.getInboxMessageForId(messageId); +``` + +#### Delete Message for the given message id + +```Dart +await CleverTapPlugin.deleteInboxMessageForId(messageId); +``` + +#### Mark Message as Read for the given message id + +```Dart +var messageList = await CleverTapPlugin.getUnreadInboxMessages(); + if (messageList == null || messageList.length == 0) return; + Map itemFirst = messageList[0]; + if (Platform.isAndroid) { + await CleverTapPlugin.markReadInboxMessageForId(itemFirst["id"]); + } else if (Platform.isIOS) { + await CleverTapPlugin.markReadInboxMessageForId(itemFirst["_id"]); + } +``` + +#### Raise Notification Viewed event for Inbox Message. Message id should be a String + +```Dart +await CleverTapPlugin.pushInboxNotificationViewedEventForId(messageId); +``` + +#### Raise Notification Clicked event for Inbox Message. Message id should be a String + +```Dart +await CleverTapPlugin.pushInboxNotificationClickedEventForId(messageId); +``` +## Debugging + +#### Set Debug Level + +```Dart +CleverTapPlugin.setDebugLevel(3); +``` + +## Push Notifications + +#### **Handle Notification Click** +Register a `setCleverTapPushClickedPayloadReceivedHandler` handler to get a notification click callback along with the entire payload. + +```Dart +_clevertapPlugin.setCleverTapPushClickedPayloadReceivedHandler(pushClickedPayloadReceived); + +void pushClickedPayloadReceived(Map notificationPayload) { + print("pushClickedPayloadReceived called with notification payload: " + notificationPayload.toString()); + // You may perform UI operation like redirecting the user to a specific page based on custom key-value pairs + // passed in the notificationPayload. You may also perform non UI operation such as HTTP requests, IO with local storage etc. + handleNotificationClick(notificationPayload); +} +``` +> **Note:** +> +> Please note that the `pushClickedPayloadReceived` handler is triggered in Android platform only when the app is in the foreground or background states, and not when it has been terminated(killed). +> However, in the case of iOS platform, this handler is supported regardless of whether the app is in the foreground, background, or has been terminated (killed). + +#### **[Android Platform] Handle Notification Trampoline Restrictions to support `pushClickedPayloadReceived` handler in Android 12 and Above** +Due to [notification trampoline restrictions](https://developer.android.com/about/versions/12/behavior-changes-12#notification-trampolines), Android 12 and above do not directly support the `pushClickedPayloadReceived` callback. +Hence, apps need to add manual handling for Android 12 and above to inform the CleverTap SDK about the notification click and get the `pushClickedPayloadReceived` callback. + +Add the following code in the `onNewIntent()` method of the Launcher `FlutterActivity` class in android: +```kotlin +class MainActivity : FlutterActivity() { + +override fun onNewIntent(intent: Intent?) { + super.onNewIntent(intent) + + // On Android 12 and above, inform the notification click to get the pushClickedPayloadReceived callback on dart side. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + cleverTapDefaultInstance?.pushNotificationClickedEvent(intent!!.extras) + } + } +} +``` + +#### **[Android Platform] Handle Notification Clicks When the App Is Killed** +The CleverTap Plugin provides two ways to handle user interactions with notifications, depending on whether the app needs to perform UI or non-UI operations. + +##### **1. Perform UI impacting operation using `CleverTapPlugin.getAppLaunchNotification()`:** +The default behavior on Android is to launch the application if the application is terminated(killed). +Use `CleverTapPlugin.getAppLaunchNotification()` to get a Future containing a notification-payload of `Map` type if the application is opened from a terminated(killed) state. +Depending on the content of a notification-payload, you may perform UI operation like redirecting the user to a specific page. + +```Dart +class Application extends StatefulWidget { + @override + State createState() => _Application(); +} + +class _Application extends State { + void _handleKilledStateNotificationInteraction() async { + // Retrieve the notification-payload in a 'CleverTapAppLaunchNotification' class object + // which caused the application to open from a terminated state. + CleverTapAppLaunchNotification appLaunchNotification = await CleverTapPlugin + .getAppLaunchNotification(); + + if (appLaunchNotification.didNotificationLaunchApp) { + //App is launched from a notification click which was rendered by the CleverTap SDK. + Map notificationPayload = appLaunchNotification.payload!; + _handleDeeplink(); + } + } + + void _handleDeeplink() { + // It is assumed that all notifications contain a data field with the key 'type' but you may also have + // a different key for deeplink handling. + var type = notificationPayload["type"]; + + if (type != null) { + print( + "_handleKilledStateNotificationInteraction => Type: $type"); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + DeepLinkPage(type: type))); + } + } -* **[Android and iOS Platform]** - * Adds in-built support to send the default locale(i.e.language and country) data to the dashboard and exposed public API `CleverTapPlugin.setLocale(Locale locale)` to set the custom locale, for LP Parity. - * Adds support for Integration Debugger to view errors and events on the dashboard when the debugLevel is set to 3 using `CleverTapPlugin.setDebugLevel(3)`. - -**Changes** -* **[iOS Platform]** - * Updated logic to retrieve country code using NSLocale above iOS 16 as `CTCarrier` is deprecated above iOS 16 with no replacements, see [apple doc](https://developer.apple.com/documentation/coretelephony/ctcarrier). - * Updated logic to not send carrier name above iOS 16 in CTCarrier field. - -**Bug Fixes** -* **[iOS Platform]** - * Fixes a crash in iOS 17/Xcode 15 related to alert inapps. - * Fixes a failing `test_clevertap_instance_nscoding` test case. - - -### Version 1.9.0 *(29th August 2023)* -------------------------------------------- -**What's new** -* **[Android Platform]** - * Supports [CleverTap Android SDK v5.2.0](https://github.com/CleverTap/clevertap-android-sdk/blob/master/docs/CTCORECHANGELOG.md#version-520-august-10-2023). - -* **[iOS Platform]** - * Supports [CleverTap iOS SDK v5.2.0](https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/5.2.0). - -* **[Android and iOS Platform]** - * Adds support for encryption of PII data wiz. Email, Identity, Name and Phone. Please refer to [Usage.md](https://github.com/CleverTap/clevertap-flutter/blob/master/doc/Usage.md#encryption-of-pii-data) file to read more on how to enable/disable encryption of PII data. - * Adds support for custom KV pairs common to all inbox messages in App Inbox. - -**Bug Fixes** -* **[Android Platform]** - * Fixes [#393](https://github.com/CleverTap/clevertap-android-sdk/issues/393) - push permission flow crash when context in CoreMetadata is null. - * Fixes a bug where addMultiValueForKey and addMultiValuesForKey were overwriting the current values of the user properties instead of appending it. - -### Version 1.8.1 *(31st July 2023)* -------------------------------------------- -**What's new** -* Supports [CleverTap iOS SDK v5.1.2](https://github.com/CleverTap/clevertap-ios-sdk/blob/master/CHANGELOG.md#version-512-july-28-2023) - -**Bug Fixes** -* **[iOS Platform]** - * Fixed a bug where the App Inbox would appear empty. - -### Version 1.8.0 *(17th July 2023)* -------------------------------------------- -**What's new** -* Supports [CleverTap Android SDK v5.1.0](https://github.com/CleverTap/clevertap-android-sdk/blob/master/docs/CTCORECHANGELOG.md#version-510-june-28-2023) -* Supports [CleverTap iOS SDK v5.1.1](https://github.com/CleverTap/clevertap-ios-sdk/blob/master/CHANGELOG.md#version-511-july-13-2023) -* ***Note: RenderMax Push SDK functionality is now supported directly within the CleverTap Core SDK***. Please remove the integrated *RenderMax SDK* before you upgrade to CleverTap Flutter SDK for this 1.8.0 version. -* Adds support for **notification click handling when the app is terminated or killed**. The CleverTap plugin provides two ways to handle user interactions with notifications, depending on whether the app needs to perform UI or non-UI operations. - * Use `CleverTapPlugin.getAppLaunchNotification()` to perform UI impacting operation like redirecting the user to a specific page. - * Use `CleverTapPlugin.onKilledStateNotificationClicked(_onKilledStateNotificationClickedHandler)` to perform non-UI operation like performing HTTP requests, IO operations with local storage etc. - Please refer to the [Notification Click Handling](https://github.com/CleverTap/clevertap-flutter/blob/master/doc/Usage.md#handle-notification-click) to learn more about properly handling notification clicks. -* ***[Android Platform]:*** Adds support for developer defined default notification channel. Please refer to the [Usage.md](https://github.com/CleverTap/clevertap-flutter/blob/master/doc/Usage.md#default-notification-channel) file to read more on how to setup default channel in your app.Also please note that this is only supported for clevertap core notifications. Support for push templates will be released soon. - -**Changes** -* The `CleverTapPlugin.createNotification(data)` API now supports rendering push template notifications and handling VoIP push for the SignedCall SDK. - -**Bug Fixes** -* **[iOS Platform]** - * Fixed Cocoapods generated duplicate UUIDs warnings. - * Mitigates potential App Inbox errors. -* **[Android Platform]** - * Fixes [#428](https://github.com/CleverTap/clevertap-android-sdk/issues/428) - Race-condition when detecting if an in-app message should show. - * Fixes Push primer alert dialog freeze behavior, which became unresponsive when clicked outside the window. - -### Version 1.7.0 *(8th June 2023)* -------------------------------------------- -**What's new** -* Adds support for **Remote Config Variables**. Please refer to the [Remote Config Variables doc](https://github.com/CleverTap/clevertap-flutter/blob/master/doc/Variables.md) to read more on how to integrate this to your app. -* Adds new API `dismissInbox()` to dismiss the App Inbox screen. -* Adds new APIs, `markReadInboxMessagesForIDs(List)` and `deleteInboxMessagesForIDs(List)` to mark read and delete an array of Inbox Messages respectively. -* Supports [CleverTap Android SDK v5.0.0](https://github.com/CleverTap/clevertap-android-sdk/blob/master/docs/CTCORECHANGELOG.md#version-500-may-5-2023) -* Supports [CleverTap iOS SDK v5.0.1](https://github.com/CleverTap/clevertap-ios-sdk/blob/master/CHANGELOG.md#version-501-may-17-2023) - -**API Changes** - -***Deprecated:*** The following methods and classes related to Product Config and Feature Flags have been marked as deprecated in this release, instead use new Remote Config Variables feature. These methods and classes will be removed in the future versions with prior notice. - -* Product config - * `setDefaultsMap` - * `fetch` - * `activate` - * `fetchAndActivate` - * `setMinimumFetchIntervalInSeconds` - * `resetProductConfig` - * `getProductConfigString` - * `getProductConfigBoolean` - * `getNumber` - * `getLastFetchTimeStampInMillis` - -* Feature flags - * `getFeatureFlag` - -**Breaking Change** -* Streamlines the payload for various callbacks across Android and iOS platform. Refer [doc](https://github.com/CleverTap/clevertap-flutter/blob/master/doc/callbackPayloadFormat.md) for detailed changes. -* ***[Android and iOS platforms] Signature change of the `CleverTapInboxNotificationMessageClickedHandler` callback]***: - It is changed from `CleverTapInboxNotificationMessageClickedHandler(Map? data)` to `CleverTapInboxNotificationMessageClickedHandler(Map? data, int contentPageIndex, int buttonIndex)`. The `contentPageIndex` corresponds to the page index of the content, which ranges from 0 to the total number of pages for carousel templates. For non-carousel templates, the `contentPageIndex` value is always 0, as they only have one page of content. The `buttonIndex` corresponds to the the App Inbox button clicked (0, 1, or 2). A value of -1 in `buttonIndex` field indicates the entire App Inbox Item is clicked. - -**Changes** -- ***[Android Platform] Behavioral change of CleverTap.CleverTapInboxMessageTapped listener:*** Previously, the callback was raised when the App Inbox item is clicked. Now, it is also raised when the App Inbox button is clicked. It matches the behavior in iOS platform. - -**Bug Fixes** -* Fixes a bug where App Inbox was not respecting the App Inbox background color when no tabs are provided. -* Fixes the non-EU retry mechanism bug. -* Fixes the data handling exception that is thrown by the `processPushNotification(dynamic data)` API. - -### Version 1.6.1 (April 4, 2023) -* Fixed compilation errors in Xcode 14.3+ in iOS. -* Streamlined the argument of `onDisplayUnitsLoaded` callback method in iOS to directly pass display unit array. -* Supports [CleverTap iOS SDK v4.2.2](https://github.com/CleverTap/clevertap-ios-sdk/blob/master/CHANGELOG.md#version-422-april-03-2023) - -### Version 1.6.0 (February 14, 2023) -* Adds below new public APIs to support [CleverTap Android SDK v4.7.4](https://github.com/CleverTap/clevertap-android-sdk/blob/master/docs/CTCORECHANGELOG.md#version-474-january-27-2023) and [CleverTap iOS SDK v4.2.0](https://github.com/CleverTap/clevertap-ios-sdk/blob/master/CHANGELOG.md#version-420-december-13-2022) - - `getPushNotificationPermissionStatus()`, `promptPushPrimer(object)`, `promptForPushNotification(boolean)` -* Adds push permission callback method `setCleverTapPushPermissionResponseReceivedHandler` which returns true/false after user allows/denies the notification permission. -* Adds `setCleverTapInAppNotificationShowHandler` to handle InApp notification shown - Only for Android. -* Streamlined the format of native display payload across Android and iOS. -* Fixes the FCM Plugin's [onBackgroundMessage handler bug](https://github.com/CleverTap/clevertap-flutter/commit/8db6f34eec83e7f14990359f88c65a50e966acb3) which was breaking the CleverTap Plugin's platform channel for sending method calls from Android. - -### Version 1.5.6 (April 5, 2023) -#### Added -* Supports [CleverTap Android SDK v4.6.9](https://github.com/CleverTap/clevertap-android-sdk/blob/master/docs/CTCORECHANGELOG.md#version-469-march-31-2023) -* Supports [CleverTap iOS SDK v4.2.2](https://github.com/CleverTap/clevertap-ios-sdk/blob/master/CHANGELOG.md#version-422-april-03-2023) -* Adds the new public API `dismissInbox()` to dismiss the App Inbox. -* **Note**: This release is being done for Android 12 targeted users. - -#### Changed -* **[Breaking change to the signature of the `CleverTapInboxNotificationMessageClickedHandler` callback]**: - It is changed from `CleverTapInboxNotificationMessageClickedHandler(Map? data)` to `CleverTapInboxNotificationMessageClickedHandler(Map? data, int contentPageIndex, int buttonIndex)`. The `contentPageIndex` corresponds to the page index of the content, which ranges from 0 to the total number of pages for carousel templates. For non-carousel templates, the `contentPageIndex` value is always 0, as they only have one page of content. The `buttonIndex` corresponds to the the App Inbox button clicked (0, 1, or 2). A value of -1 in `buttonIndex` field indicates the entire App Inbox Item is clicked. -* **[Behavioral change of the `CleverTapInboxNotificationMessageClickedHandler` callback]**: - Previously, the callback was raised when the App Inbox Item is clicked. Now, it is also raised when the App Inbox button is clicked besides the item click. -* **[Native Display parity changes]**: - - Streamlines the format of native display payload across Android and iOS. - - Streamlines the argument of `onDisplayUnitsLoaded` callback method in iOS to pass the list of displayUnits. - -#### Fixed -* Fixes the FCM Plugin's [onBackgroundMessage handler bug](https://github.com/CleverTap/clevertap-flutter/commit/8db6f34eec83e7f14990359f88c65a50e966acb3) which was breaking the CleverTap Plugin's platform channel for sending method calls from Android to Dart platform. -* Fixes the Xcode 14.3+ compilation errors in iOS. - -### Version 1.5.5 (January 23, 2023) -* Adds fix for closing App Inbox controller when deeplink is present in iOS. -* Supports [add-to-app](https://docs.flutter.dev/development/add-to-app) feature for Android platform to embed the CleverTap plugin in a flutter module. - -### Version 1.5.4 (November 4, 2022) -* Supports [CleverTap iOS SDK v4.1.4](https://github.com/CleverTap/clevertap-ios-sdk/blob/master/CHANGELOG.md#version-414-october-24-2022) - -### Version 1.5.3 (October 28, 2022) -* Fixes incorrect API being called in `profileAddMultiValues` in iOS. - -### Version 1.5.2 (October 7, 2022) -* Supports [CleverTap Android SDK v4.6.3](https://github.com/CleverTap/clevertap-android-sdk/releases/tag/corev4.6.3) -* [Breaking Change] `setXiaomiPushToken` API has been modified to accept region to comply with new Mi Push Region changes. Refer to [CleverTap Xiaomi Push SDK v1.5.0 Changelog](https://github.com/CleverTap/clevertap-android-sdk/blob/master/docs/CTXIAOMIPUSHCHANGELOG.md) -* Supports [CleverTap iOS SDK v4.1.2](https://github.com/CleverTap/clevertap-ios-sdk/blob/master/CHANGELOG.md#version-412-september-16-2022) - -### Version 1.5.1 (April 7, 2022) -* Adds the missing getter methods for Product Config in iOS. - -### Version 1.5.0 (March 8, 2022) -* Supports [CleverTap Android SDK v4.4.0](https://github.com/CleverTap/clevertap-android-sdk/releases/tag/core-v4.4.0) -* Supports [CleverTap iOS SDK v4.0.0](https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/4.0.0) - -### Version 1.4.0 (December 1, 2021) -* Adds fix for NPE [#61](https://github.com/CleverTap/clevertap-flutter/issues/61) -* Adds `result.success(null)` for all method calls [#81](https://github.com/CleverTap/clevertap-flutter/issues/81) -* Supports [CleverTap Android SDK v4.3.1](https://github.com/CleverTap/clevertap-android-sdk/releases/tag/core-v4.3.1) - -### Version 1.3.0 (September 13, 2021) -* Adds public methods for suspending, discarding & resuming InApp Notifications -* Adds public methods to increment/decrement values set via User properties -* Deprecates `profileGetCleverTapID()` and `profileGetCleverTapAttributionIdentifier()` methods -* Adds a new public method `getCleverTapID()` as an alternative to above deprecated methods -* Supports [CleverTap iOS SDK v3.10.0](https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/3.10.0) - -### Version 1.2.3 (July 20, 2021) -* Supports [CleverTap Android SDK v4.2.0](https://github.com/CleverTap/clevertap-android-sdk/releases/tag/core-v4.2.0) -* Adds fix for NPE [#58](https://github.com/CleverTap/clevertap-flutter/issues/58) -* Adds fix for `recordScreen` NPE [#54](https://github.com/CleverTap/clevertap-flutter/issues/54) - -### Version 1.2.2 (May 21, 2021) -* Supports [CleverTap Android SDK v4.1.1](https://github.com/CleverTap/clevertap-android-sdk/releases/tag/core-v4.1.1) -* Supports [CleverTap iOS SDK v3.9.4](https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/3.9.4) -* Removes Product A/B Testing (Dynamic Variables) code -* Removes `profileSetGraphUser` method -* Adds `pushNotificationViewedEvent` and `pushNotificationClickedEvent` - -### Version 1.2.1 (April 23, 2021) -* Update and Freeze [CleverTap Plugin Podspec](https://github.com/CleverTap/clevertap-flutter/blob/master/ios/clevertap_plugin.podspec) to a specific version of a CleverTap iOS SDK - -### Version 1.2.0 (October 13, 2020) -* Supports [CleverTap Android SDK v4.0.0](https://github.com/CleverTap/clevertap-android-sdk/releases/tag/core-v4.0.0) -* Supports [CleverTap iOS SDK v3.9.1](https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/3.9.1) - -### Version 1.1.4 (August 4, 2020) -* Supports [CleverTap Android SDK v3.8.2](https://github.com/CleverTap/clevertap-android-sdk/releases/tag/3.8.2) - -### Version 1.1.3 (July 17, 2020) -* Use v1.1.4 -* Adds a callback to provide Push Notifications custom key-value pairs -* Supports CleverTap [Android](https://github.com/CleverTap/clevertap-android-sdk/releases/tag/3.8.1) and [iOS](https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/3.8.1) SDK v3.8.1 -* Sample App Updated - -### Version 1.1.2 (May 20, 2020) -* Use v1.1.4 -* Adds support for Product Config and Feature Flags -* Adds support for Custom Handling Push Amplification Campaigns -* Supports CleverTap [Android](https://github.com/CleverTap/clevertap-android-sdk/releases/tag/3.8.0) and [iOS](https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/3.8.0) SDK v3.8.0 - -### Version 1.1.1 (March 30, 2020) -* Use v1.1.4 -* Adds support for Custom App Inbox -* Adds support for InApp/Inbox button click listeners -* Adds support for Notification Clicked/Viewed for App Inbox -* Adds support for passing Xiaomi/Baidu tokens. -* Supports [CleverTap Android SDK v3.7.2](https://github.com/CleverTap/clevertap-android-sdk/releases/tag/3.7.2) -* Supports [CleverTap iOS SDK v3.7.3](https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/3.7.3) - -### Version 1.1.0 (February 27, 2020) -* Adds support for Dynamic Variables & Native Display -* Adds support for Google Play Install Referrer Library v1.0 -* Supports CleverTap Android SDK v3.6.4 -* Supports CleverTap iOS SDK v3.7.2 - -### Version 1.0.0 (January 20, 2020) -* Initial Release. -* Supports CleverTap Android SDK v3.6.1 -* Supports CleverTap iOS SDK v3.7.2 + @override + void initState() { + super.initState(); + + // Run CleverTapPlugin.getAppLaunchNotification in an async function + // as initState() must not be async + if (Platform.isAndroid) { + _handleKilledStateNotificationInteraction(); + } + } + + @override + Widget build(BuildContext context) { + return Text("..."); + } +} +``` + +> **Note:** +> +> The notification needs to be generated by the CleverTap SDK to get the notification payload from the +> `CleverTapPlugin.getAppLaunchNotification()` API. + + +##### **2. Perform non-UI operation using `onKilledStateNotificationClicked` handler:** +There are two steps to setup the `onKilledStateNotificationClicked` handler: +1. Your `Application` class should extend the `CleverTapApplication` class instead of the `FlutterApplication` class. +2. Register the `onKilledStateNotificationClicked` handler to get a notification click callback along with the entire payload. When notification is clicked, an isolate is spawned (Android only) allowing you to handle notification click even when your application is not running. +There are a few things to keep in mind about your `onKilledStateNotificationClicked` handler: + - It must not be an anonymous function. + - It must be a top-level function (e.g. not a class method which requires initialization). + - When using Flutter version 3.3.0 or higher, the `onKilledStateNotificationClicked` handler must be annotated with `@pragma('vm:entry-point')` right above the function declaration (otherwise it may be removed during tree shaking for release mode). + +Add the following method to your `main.dart` file, right after the import statements, and outside any Widget class declaration, to process push notifications in the killed state via a Flutter background isolate: + +```Dart +@pragma('vm:entry-point') +void _onKilledStateNotificationClickedHandler(Map map) async { + print("Notification Payload received: " + map.toString()); +} + +void main() { + CleverTapPlugin.onKilledStateNotificationClicked(_onKilledStateNotificationClickedHandler); + runApp(MyApp()); +} +``` + +> **Note:** +> +> Since the `_onKilledStateNotificationClickedHandler` handler runs in its own isolate outside your applications context, it is not possible to update application state or execute any UI operation from the handler itself. +> You can, however, perform HTTP requests, IO operations with local storage etc. + +#### Creating Notification Channel + +```Dart +CleverTapPlugin.createNotificationChannel("fluttertest", "Flutter Test", "Flutter Test", 3, true); +``` + +#### Default Notification Channel +Starting from CleverTap Plugin v1.8.0 we have introduced a new feature that allows developers to define a default notification channel for their app. This feature provides flexibility in handling push notifications. +Please note that this is only supported for clevertap core notifications. Support for push templates will be released soon. To specify the default notification channel ID, you can add the following metadata in your app's manifest file: + +```XML + +``` + +By including this metadata, you can define a specific notification channel that CleverTap will use if the channel provided in push payload is not registered by your app. This ensures that push notifications are displayed consistently even if the app's notification channels are not set up. + +In case the SDK does not find the default channel ID specified in the manifest, it will automatically fallback to using a default channel called "Miscellaneous". This ensures that push notifications are still delivered, even if no specific default channel is specified in the manifest. + +This enhancement provides developers with greater control over the default notification channel used by CleverTap for push notifications, ensuring a seamless and customizable user experience. + +#### Delete Notification Channel + +```Dart +CleverTapPlugin.deleteNotificationChannel(“channelId”); +``` + +#### Creating a group notification channel + +```Dart +CleverTapPlugin.createNotificationChannelGroup(“groupId”, “groupName”); +``` + +#### Delete a group notification channel + +```Dart +CleverTapPlugin.deleteNotificationChannelGroup(“channelId”); +``` + +#### Registering Fcm, Baidu, Xiaomi, Huawei Token + +```Dart +CleverTapPlugin.setPushToken(“value”); +CleverTapPlugin.setBaiduPushToken(“value”); +CleverTapPlugin.setXiaomiPushToken(“value”); +CleverTapPlugin.setHuaweiPushToken(“value”); +``` + + #### Create Notification + +```Dart +CleverTapPlugin.createNotification(data); +``` + +------ + +## Custom Push Amplification + +#### Process Push Notification + +```Dart + CleverTapPlugin.processPushNotification(data); +``` + +--------- + +## Native Display + +#### On Display Units Loaded + +```Dart +void onDisplayUnitsLoaded(List displayUnits) { + this.setState(() { + print("Display Units = " + displayUnits.toString()); + }); +} +``` + +#### Get All Display Units + +```Dart +void onDisplayUnitsLoaded(List displayUnits) { + this.setState(() async { + List displayUnits = await CleverTapPlugin.getAllDisplayUnits(); + print("Display Units = " + displayUnits.toString()); + }); +} +``` + +#### Display unit viewed event for ID + +```Dart +CleverTapPlugin.pushDisplayUnitViewedEvent(“unitId”); +``` +#### Display unit clicked event for ID + +```Dart +CleverTapPlugin.pushDisplayUnitClickedEvent(“unitId”); +``` + +## Product Config + +#### Set Product Configuration to default + +```Dart +void productConfigInitialized() { + print("Product Config Initialized"); + this.setState(() async { + await CleverTapPlugin.fetch(); + }); +} +``` + +#### Fetching product configs + +```Dart +void fetch() { + CleverTapPlugin.fetch(); + // CleverTapPlugin.fetchWithMinimumIntervalInSeconds(0); +} +``` + +#### Activate the most recently fetched product config + +```Dart +void activate() { + CleverTapPlugin.activate(); +} +``` + +#### Fetch And Activate product config + +```Dart +void fetchAndActivate() { + CleverTapPlugin.fetchAndActivate(); + } +``` + +#### Fetch Minimum Time Interval + +```Dart +CleverTapPlugin.setMinimumFetchIntervalInSeconds(interval); +``` + +#### Get Boolean key + +```Dart + CleverTapPlugin.getProductConfigBoolean(“key”); +``` + +#### Get last fetched timestamp in millis + +```Dart +CleverTapPlugin.getLastFetchTimeStampInMillis(); +``` + +## Feature Flag + +#### Get Feature Flag + +```Dart +void featureFlagsUpdated() { + this.setState(() async { + bool booleanVar = await CleverTapPlugin.getFeatureFlag("BoolKey", false); + }); +} +``` + +## App Personalization + +#### Enable Personalization + +```Dart +CleverTapPlugin.enablePersonalization(); +``` + +#### Disable Personalization + +```Dart +CleverTapPlugin.disablePersonalization(); +``` + +## Attributions + +#### Push Install Refferer + +```Dart +CleverTapPlugin.pushInstallReferrer("source", "medium", "campaign"); +``` + +## GDPR + +#### Set Opt Out + +```Dart +CleverTapPlugin.setOptOut(false); ///Will opt in the user to send data to CleverTap +CleverTapPlugin.setOptOut(true); ///Will opt out the user to send data to CleverTap +``` + +#### Enable Device Networking Info Reporting + +```Dart +// Will opt out the user to send Device Network data to CleverTap +CleverTapPlugin.enableDeviceNetworkInfoReporting(false); +// Will opt in the user to send Device Network data to CleverTap +CleverTapPlugin.enableDeviceNetworkInfoReporting(true); +``` + +## Set Offline + +```Dart +// Will set the user online +CleverTapPlugin.setOffline(false); +// Will set the user offline +CleverTapPlugin.setOffline(true); +``` + +----------- + +## Push primer for notification Permission (Android and iOS) +Follow the [Push Primer integration doc](PushPrimer.md). + +## Encryption of PII data (Android and iOS) +PII data is stored across the SDK and could be sensitive information. From CleverTap Flutter SDK v1.9.0 onwards, you can enable encryption for PII data wiz. Email, Identity, Name and Phone. + +Currently 2 levels of encryption are supported i.e None(0) and Medium(1). Encryption level is None by default. +**None** - All stored data is in plaintext +**Medium** - PII data is encrypted completely. + +#### Android +Add encryption level in the `AndroidManifest.xml` as following: +```XML + +``` +#### iOS +Add the `CleverTapEncryptionLevel` String key to `info.plist` file where value 1 means Medium and 0 means None. Encryption Level will be None if any other value is provided. + + +### For more information, + + - [See Example Application Dart interface](/example/lib/main.dart) + - [See CleverTap Dart interface](/lib/clevertap_plugin.dart) + + diff --git a/pubspec.yaml b/pubspec.yaml index 85b93c33..e0935a94 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: clevertap_plugin description: The CleverTap Flutter SDK for Mobile Customer Engagement,Analytics and Retention solutions. -version: 1.9.0 +version: 1.9.1 homepage: https://github.com/CleverTap/clevertap-flutter environment: From b071ba3f4aa2e82e002f21d5fac911e0f29f841b Mon Sep 17 00:00:00 2001 From: Nishant Kumar Date: Fri, 20 Oct 2023 14:12:22 +0530 Subject: [PATCH 6/7] Updated Library version, Readme and changelog docs --- CHANGELOG.md | 1 - README.md | 2 +- lib/clevertap_plugin.dart | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b782a69..edd13745 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,7 +23,6 @@ **Bug Fixes** * **[iOS Platform]** * Fixes a crash in iOS 17/Xcode 15 related to alert inapps. - * Fixes a failing `test_clevertap_instance_nscoding` test case. ### Version 1.9.0 *(29th August 2023)* diff --git a/README.md b/README.md index bf7a1f83..d43f52be 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ To get started, sign up [here](https://clevertap.com/live-product-demo/). ```yaml dependencies: -clevertap_plugin: 1.9.0 +clevertap_plugin: 1.9.1 ``` - Run `flutter packages get` to install the SDK diff --git a/lib/clevertap_plugin.dart b/lib/clevertap_plugin.dart index 2a8a648d..95592025 100644 --- a/lib/clevertap_plugin.dart +++ b/lib/clevertap_plugin.dart @@ -54,7 +54,7 @@ class CleverTapPlugin { factory CleverTapPlugin() => _clevertapPlugin; static const libName = 'Flutter'; - static const libVersion = 10900; // If the current version is X.X.X then pass as X0X0X + static const libVersion = 10901; // If the current version is X.X.X then pass as X0X0X CleverTapPlugin._internal() { /// Set the CleverTap Flutter library name and the current version for version tracking From 335a1fda07d8df8fc8242e4729fd75931ac5dc7f Mon Sep 17 00:00:00 2001 From: Nishant Kumar Date: Fri, 20 Oct 2023 14:17:46 +0530 Subject: [PATCH 7/7] Updated plugin version in iOS podspec file --- ios/clevertap_plugin.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/clevertap_plugin.podspec b/ios/clevertap_plugin.podspec index c278b947..52989470 100644 --- a/ios/clevertap_plugin.podspec +++ b/ios/clevertap_plugin.podspec @@ -3,7 +3,7 @@ # Pod::Spec.new do |s| s.name = 'clevertap_plugin' - s.version = '1.7.0' + s.version = '1.9.1' s.summary = 'CleverTap Flutter plugin.' s.description = 'The CleverTap iOS SDK for App Analytics and Engagement.' s.homepage = 'https://github.com/CleverTap/clevertap-ios-sdk'