diff --git a/.gitignore b/.gitignore
index e4498c7..282d3e4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,5 @@
example/ios/Podfile.lock
-example/pubspec.lock
\ No newline at end of file
+example/pubspec.lock
+.dart_tool/
+build/
+pubspec.lock
\ No newline at end of file
diff --git a/android/build.gradle b/android/build.gradle
index f16601e..d5d7c78 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -25,7 +25,7 @@ apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
android {
- compileSdkVersion 31
+ compileSdkVersion 33
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
@@ -42,7 +42,10 @@ android {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
- implementation 'com.iterable:iterableapi:3.4.9'
+ implementation 'com.iterable:iterableapi:3.4.15'
+ implementation 'com.iterable:iterableapi-ui:3.4.0'
+ // Version 17.4.0+ is required for push notifications and in-app message features:
+ implementation 'com.google.firebase:firebase-messaging:17.4.0'
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.json:json:20210307'
}
diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml
index 34532b9..29dc62b 100644
--- a/android/src/main/AndroidManifest.xml
+++ b/android/src/main/AndroidManifest.xml
@@ -1,3 +1,4 @@
+
diff --git a/android/src/main/kotlin/com/lahaus/iterable_flutter/IterableFlutterPlugin.kt b/android/src/main/kotlin/com/lahaus/iterable_flutter/IterableFlutterPlugin.kt
index 5ab42e6..0337d2d 100644
--- a/android/src/main/kotlin/com/lahaus/iterable_flutter/IterableFlutterPlugin.kt
+++ b/android/src/main/kotlin/com/lahaus/iterable_flutter/IterableFlutterPlugin.kt
@@ -15,6 +15,8 @@ import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import org.json.JSONObject
import java.util.*
+import java.net.URL
+
/** IterableFlutterPlugin */
@@ -52,9 +54,9 @@ class IterableFlutterPlugin : FlutterPlugin, MethodCallHandler {
result.success(null)
}
"setEmail" -> {
- val userEmail = call.arguments as String
- IterableApi.getInstance().setEmail(userEmail)
- IterableApi.getInstance().registerForPush()
+ val email = call.argument("email") ?: ""
+ val jwt = call.argument("jwt") ?: ""
+ IterableApi.getInstance().setEmail(email, jwt)
result.success(null)
}
"setUserId" -> {
@@ -93,6 +95,14 @@ class IterableFlutterPlugin : FlutterPlugin, MethodCallHandler {
IterableApi.getInstance().updateUser(JSONObject(userInfo))
result.success(null)
}
+ "handleDeepLink" -> {
+ val argumentData = call.arguments as? Map<*, *>
+ val url = argumentData?.get("url") as String
+ IterableApi.getInstance().getAndTrackDeepLink(url) { result:String? ->
+ Log.d("HandleDeeplink", "Redirected to: $result")
+ channel.invokeMethod("deepLinkHandler", mapOf("path" to URL(result).path))
+ }
+ }
else -> {
result.notImplemented()
}
@@ -107,11 +117,10 @@ class IterableFlutterPlugin : FlutterPlugin, MethodCallHandler {
notifyPushNotificationOpened()
false
}
-
+
if (activeLogDebug) {
- configBuilder.setLogLevel(Log.DEBUG)
+ configBuilder.setLogLevel(Log.VERBOSE)
}
-
IterableApi.initialize(context, apiKey, configBuilder.build())
}
diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle
index 1ecbeb6..ba25d6c 100644
--- a/example/android/app/build.gradle
+++ b/example/android/app/build.gradle
@@ -29,7 +29,7 @@ apply from: project(':flutter_config').projectDir.getPath() + "/dotenv.gradle"
apply plugin: 'com.google.gms.google-services'
android {
- compileSdkVersion 31
+ compileSdkVersion 33
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
@@ -39,7 +39,7 @@ android {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.lahaus.iterable_flutter_example"
minSdkVersion 16
- targetSdkVersion 31
+ targetSdkVersion 33
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
diff --git a/ios/Classes/SwiftIterableFlutterPlugin.swift b/ios/Classes/SwiftIterableFlutterPlugin.swift
index c08907e..8e3161d 100644
--- a/ios/Classes/SwiftIterableFlutterPlugin.swift
+++ b/ios/Classes/SwiftIterableFlutterPlugin.swift
@@ -3,17 +3,34 @@ import UIKit
import IterableSDK
import UserNotifications
-public class SwiftIterableFlutterPlugin: NSObject, FlutterPlugin, UNUserNotificationCenterDelegate, IterableCustomActionDelegate, IterableURLDelegate {
+public class SwiftIterableFlutterPlugin: NSObject, FlutterPlugin, UNUserNotificationCenterDelegate, IterableCustomActionDelegate, IterableURLDelegate, IterableAuthDelegate {
static var channel: FlutterMethodChannel? = nil
+ var token: String? = nil
public static func register(with registrar: FlutterPluginRegistrar) {
+ NSLog("calling channel register")
channel = FlutterMethodChannel(name: "iterable_flutter", binaryMessenger: registrar.messenger())
let instance = SwiftIterableFlutterPlugin()
registrar.addMethodCallDelegate(instance, channel: channel!)
registrar.addApplicationDelegate(instance)
}
+
+ public func onAuthTokenRequested(completion: @escaping AuthTokenRetrievalHandler) {
+ print("calling onAuthTokenRequested")
+ print(token)
+ completion(token)
+ }
+
+ public func onAuthFailure(_ authFailure: AuthFailure) {
+
+ }
+
+ public func onTokenRegistrationFailed(_ reason: String?) {
+ print("token registration failed")
+ print(reason)
+ }
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch (call.method) {
@@ -22,14 +39,17 @@ public class SwiftIterableFlutterPlugin: NSObject, FlutterPlugin, UNUserNotifica
let apiKey = args["apiKey"] as! String
let pushIntegrationName = args["pushIntegrationName"] as! String
-
initialize(apiKey, pushIntegrationName)
result(nil)
case "setEmail":
- let email = call.arguments as! String
- IterableAPI.email = email
-
+ let args = getPropertiesFromArguments(call.arguments)
+ let email = args["email"] as! String
+ let jwt = args["jwt"] as! String
+ print("calling IterableAPI.setEmail")
+ token = jwt
+ IterableAPI.setEmail(email, jwt)
+ print("finished calling IterableAPI.setEmail")
result(nil)
case "setUserId":
let userId = call.arguments as! String
@@ -67,6 +87,14 @@ public class SwiftIterableFlutterPlugin: NSObject, FlutterPlugin, UNUserNotifica
case "signOut":
signOut()
+ result(nil)
+ case "handleDeepLink":
+ NSLog("NSLog handleDeepLink")
+ let args = getPropertiesFromArguments(call.arguments)
+ let urlStr = args["url"] as! String
+ NSLog("deeplink \(urlStr)")
+ let url = URL(string: urlStr)
+ IterableAPI.handle(universalLink: url!)
result(nil)
default:
result(FlutterMethodNotImplemented)
@@ -76,10 +104,11 @@ public class SwiftIterableFlutterPlugin: NSObject, FlutterPlugin, UNUserNotifica
private func initialize(_ apiKey: String, _ pushIntegrationName: String){
let config = IterableConfig()
config.pushIntegrationName = pushIntegrationName
- config.autoPushRegistration = true
+ config.autoPushRegistration = false
config.customActionDelegate = self
config.urlDelegate = self
-
+ config.authDelegate = self
+ config.logDelegate = AllLogDelegate()
IterableAPI.initialize(apiKey: apiKey, config: config)
}
@@ -95,12 +124,14 @@ public class SwiftIterableFlutterPlugin: NSObject, FlutterPlugin, UNUserNotifica
}
public func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [AnyHashable : Any] = [:]) -> Bool {
+ print("application")
UNUserNotificationCenter.current().delegate = self
return true
}
-
+
public func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
+ print("~~~~~ calling IterableAPI.register")
IterableAPI.register(token: deviceToken)
}
@@ -132,7 +163,15 @@ public class SwiftIterableFlutterPlugin: NSObject, FlutterPlugin, UNUserNotifica
public func handle(iterableURL url: URL, inContext context: IterableActionContext) -> Bool {
- notifyPushNotificationOpened()
+ NSLog("deeplink: handle(iterableURL url: URL,")
+ NSLog("deeplink \(url.path)")
+ let payload = [
+ "path": url.path ?? "",
+ "query": url.query ?? ""
+ ] as [String : Any]
+ NSLog("calling deepLinkHandler up the channel")
+ NSLog("is there a channel? \(SwiftIterableFlutterPlugin.channel == nil)")
+ SwiftIterableFlutterPlugin.channel?.invokeMethod("deepLinkHandler", arguments: payload)
return true
}
@@ -151,7 +190,5 @@ public class SwiftIterableFlutterPlugin: NSObject, FlutterPlugin, UNUserNotifica
] as [String : Any]
SwiftIterableFlutterPlugin.channel?.invokeMethod("openedNotificationHandler", arguments: payload)
-
}
-
}
diff --git a/ios/iterable_flutter.podspec b/ios/iterable_flutter.podspec
index 5a559a4..1f31d1c 100644
--- a/ios/iterable_flutter.podspec
+++ b/ios/iterable_flutter.podspec
@@ -15,7 +15,7 @@ Pod::Spec.new do |s|
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.dependency 'Flutter'
- s.dependency 'Iterable-iOS-SDK', '6.4.7'
+ s.dependency 'Iterable-iOS-SDK', '6.5.7'
s.platform = :ios, '11.0'
# Flutter.framework does not contain a i386 slice.
diff --git a/lib/iterable_flutter.dart b/lib/iterable_flutter.dart
index 09d0386..79a63aa 100644
--- a/lib/iterable_flutter.dart
+++ b/lib/iterable_flutter.dart
@@ -4,17 +4,19 @@ import 'dart:convert';
import 'package:flutter/services.dart';
typedef OpenedNotificationHandler = void Function(Map openedResult);
+typedef OpenedDeepLinkHandler = void Function(Map openedResult);
// ignore: avoid_classes_with_only_static_members
class IterableFlutter {
static const MethodChannel _channel = MethodChannel('iterable_flutter');
static OpenedNotificationHandler? _onOpenedNotification;
+ static OpenedDeepLinkHandler? _onOpenedDeepLink;
static Future initialize({
required String apiKey,
required String pushIntegrationName,
- bool activeLogDebug = false,
+ bool activeLogDebug = false
}) async {
await _channel.invokeMethod(
'initialize',
@@ -27,8 +29,20 @@ class IterableFlutter {
_channel.setMethodCallHandler(nativeMethodCallHandler);
}
- static Future setEmail(String email) async {
- await _channel.invokeMethod('setEmail', email);
+ static Future setEmail(String email, String jwt) async {
+ await _channel.invokeMethod(
+ 'setEmail',
+ {
+ 'email': email,
+ 'jwt': jwt,
+ },
+ );
+ }
+
+ static Future handleDeepLink(url) async {
+ print("handleDeepLink");
+ print(url);
+ await _channel.invokeMethod("handleDeepLink", {'url': url});
}
static Future setUserId(String userId) async {
@@ -69,14 +83,23 @@ class IterableFlutter {
_onOpenedNotification = handler;
}
+ static void setDeepLinkOpenedHandler(OpenedDeepLinkHandler handler) {
+ print("calling setDeepLinkOpenedHandler ");
+ _onOpenedDeepLink = handler;
+ }
+
static Future nativeMethodCallHandler(MethodCall methodCall) async {
+ print("nativeMethodCallHandler maybe deep? ${methodCall.method}");
final arguments = methodCall.arguments as Map;
final argumentsCleaned = sanitizeArguments(arguments);
-
switch (methodCall.method) {
case "openedNotificationHandler":
_onOpenedNotification?.call(argumentsCleaned);
return "This data from native.....";
+ case "deepLinkHandler":
+ print("deepLinkHandler running... ");
+ _onOpenedDeepLink?.call(argumentsCleaned);
+ return "Deep link datta from handler...";
default:
return "Nothing";
}
@@ -86,7 +109,7 @@ class IterableFlutter {
Map arguments) {
final result = arguments;
- final data = result['additionalData'];
+ final data = result['additionalData'] ?? {};
data.forEach((key, value) {
if (value is String) {
if (value[0] == '{' && value[value.length - 1] == '}') {
diff --git a/pubspec.yaml b/pubspec.yaml
index c086c15..b20252b 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
name: iterable_flutter
description: Flutter implementation for iterable.com Cross Channel Marketing Platform
-version: 0.5.8
+version: 0.9.3
homepage: https://lahaus.com
repository: https://github.com/la-haus/iterable-flutter
issue_tracker: https://github.com/la-haus/iterable-flutter/issues
diff --git a/test/iterable_flutter_test.dart b/test/iterable_flutter_test.dart
index 75f4a23..5f22591 100644
--- a/test/iterable_flutter_test.dart
+++ b/test/iterable_flutter_test.dart
@@ -13,7 +13,9 @@ void main() {
const String activeLogDebug = 'activeLogDebug';
const String email = 'my@email.com';
const String userId = '11111';
+ const String jwt = '';
const String event = 'my_event';
+ const String authToken = 'authToken';
const Map dataFields = {'data': 'field'};
const contentBody = {'testKey': "Test body push"};
@@ -64,16 +66,20 @@ void main() {
arguments: {
apiKey: apiKey,
pushIntegrationName: pushIntegrationName,
- activeLogDebug: false
+ activeLogDebug: false,
+ authToken: null
},
),
]);
});
test('setEmail', () async {
- await IterableFlutter.setEmail(email);
+ await IterableFlutter.setEmail(email, jwt);
expect(calledMethod, [
- isMethodCall('setEmail', arguments: email),
+ isMethodCall('setEmail', arguments: {
+ "email": email,
+ "jwt": jwt
+ }),
]);
});