diff --git a/android/src/main/kotlin/io/customer/customer_io/constant/Keys.kt b/android/src/main/kotlin/io/customer/customer_io/constant/Keys.kt index 68d7773..bc8e1dd 100644 --- a/android/src/main/kotlin/io/customer/customer_io/constant/Keys.kt +++ b/android/src/main/kotlin/io/customer/customer_io/constant/Keys.kt @@ -15,6 +15,7 @@ internal object Keys { const val TRACK_METRIC = "trackMetric" const val ON_MESSAGE_RECEIVED = "onMessageReceived" const val DISMISS_MESSAGE = "dismissMessage" + const val GET_REGISTERED_DEVICE_TOKEN = "getRegisteredDeviceToken" } object Tracking { diff --git a/android/src/main/kotlin/io/customer/customer_io/messagingpush/CustomerIOPushMessaging.kt b/android/src/main/kotlin/io/customer/customer_io/messagingpush/CustomerIOPushMessaging.kt index 26a0435..cb8cc88 100644 --- a/android/src/main/kotlin/io/customer/customer_io/messagingpush/CustomerIOPushMessaging.kt +++ b/android/src/main/kotlin/io/customer/customer_io/messagingpush/CustomerIOPushMessaging.kt @@ -6,6 +6,7 @@ import io.customer.customer_io.constant.Keys import io.customer.customer_io.getAsTypeOrNull import io.customer.customer_io.invokeNative import io.customer.messagingpush.CustomerIOFirebaseMessagingService +import io.customer.sdk.CustomerIO import io.customer.sdk.core.di.SDKComponent import io.customer.sdk.core.util.Logger import io.flutter.embedding.engine.plugins.FlutterPlugin @@ -28,6 +29,11 @@ internal class CustomerIOPushMessaging( override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { when (call.method) { + Keys.Methods.GET_REGISTERED_DEVICE_TOKEN -> { + call.invokeNative(result) { + return@invokeNative getRegisteredDeviceToken() + } + } Keys.Methods.ON_MESSAGE_RECEIVED -> { call.invokeNative(result) { args -> return@invokeNative onMessageReceived( @@ -43,6 +49,10 @@ internal class CustomerIOPushMessaging( } } + private fun getRegisteredDeviceToken(): String? { + return CustomerIO.instance().registeredDeviceToken + } + /** * Handles push notification received. This is helpful in processing push notifications * received outside the CIO SDK. diff --git a/apps/amiapp_flutter/lib/src/customer_io.dart b/apps/amiapp_flutter/lib/src/customer_io.dart index fb1b2d5..9c8d398 100644 --- a/apps/amiapp_flutter/lib/src/customer_io.dart +++ b/apps/amiapp_flutter/lib/src/customer_io.dart @@ -127,10 +127,6 @@ extension AmiAppSDKExtensions on CustomerIOSDK { return null; } } - - Future getDeviceToken() async { - return null; - } } /// Customer.io SDK extensions to save/retrieve configurations to/from preferences. diff --git a/apps/amiapp_flutter/lib/src/screens/settings.dart b/apps/amiapp_flutter/lib/src/screens/settings.dart index 92414da..1f0c874 100644 --- a/apps/amiapp_flutter/lib/src/screens/settings.dart +++ b/apps/amiapp_flutter/lib/src/screens/settings.dart @@ -1,3 +1,4 @@ +import 'package:customer_io/customer_io.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:go_router/go_router.dart'; @@ -48,7 +49,7 @@ class _SettingsScreenState extends State { @override void initState() { - widget._customerIOSDK.getDeviceToken().then((value) => + CustomerIO.instance.pushMessaging.getRegisteredDeviceToken().then((value) => setState(() => _deviceTokenValueController.text = value ?? '')); final cioConfig = widget._customerIOSDK.sdkConfig; @@ -201,7 +202,8 @@ class _SettingsScreenState extends State { semanticsLabel: 'API Host Input', hintText: 'cdp.customer.io/v1', valueController: _apiHostValueController, - validator: (value) => value?.isEmptyOrValidUrl() != false + validator: (value) => value?.isEmptyOrValidUrl() != + false ? null : 'Please enter url e.g. cdp.customer.io/v1 (without https)', ), @@ -211,7 +213,8 @@ class _SettingsScreenState extends State { semanticsLabel: 'CDN Host Input', hintText: 'cdp.customer.io/v1', valueController: _cdnHostValueController, - validator: (value) => value?.isEmptyOrValidUrl() != false + validator: (value) => value?.isEmptyOrValidUrl() != + false ? null : 'Please enter url e.g. cdp.customer.io/v1 (without https)', ), diff --git a/ios/Classes/Keys.swift b/ios/Classes/Keys.swift index 087ac63..fc8117d 100644 --- a/ios/Classes/Keys.swift +++ b/ios/Classes/Keys.swift @@ -14,6 +14,7 @@ struct Keys { static let registerDeviceToken = "registerDeviceToken" static let trackMetric = "trackMetric" static let dismissMessage = "dismissMessage" + static let getRegisteredDeviceToken = "getRegisteredDeviceToken" } struct Tracking { diff --git a/ios/Classes/MessagingPush/CustomerIOMessagingPush.swift b/ios/Classes/MessagingPush/CustomerIOMessagingPush.swift new file mode 100644 index 0000000..0cb6760 --- /dev/null +++ b/ios/Classes/MessagingPush/CustomerIOMessagingPush.swift @@ -0,0 +1,45 @@ +import CioDataPipelines +import Flutter +import Foundation + +public class CustomerIOMessagingPush: NSObject, FlutterPlugin { + private let channelName: String = "customer_io_messaging_push" + + public static func register(with registrar: FlutterPluginRegistrar) { + } + + private var methodChannel: FlutterMethodChannel? + + init(with registrar: FlutterPluginRegistrar) { + super.init() + + methodChannel = FlutterMethodChannel( + name: channelName, binaryMessenger: registrar.messenger()) + guard let methodChannel = methodChannel else { + print("\(channelName) methodChannel is nil") + return + } + + registrar.addMethodCallDelegate(self, channel: methodChannel) + } + + deinit { + detachFromEngine() + } + + public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + // Handle method calls for this method channel + switch call.method { + case Keys.Methods.getRegisteredDeviceToken: + result(CustomerIO.shared.registeredDeviceToken) + + default: + result(FlutterMethodNotImplemented) + } + } + + func detachFromEngine() { + methodChannel?.setMethodCallHandler(nil) + methodChannel = nil + } +} diff --git a/ios/Classes/SwiftCustomerIoPlugin.swift b/ios/Classes/SwiftCustomerIoPlugin.swift index 78ae4c0..a96316d 100644 --- a/ios/Classes/SwiftCustomerIoPlugin.swift +++ b/ios/Classes/SwiftCustomerIoPlugin.swift @@ -8,6 +8,7 @@ public class SwiftCustomerIoPlugin: NSObject, FlutterPlugin { private var methodChannel: FlutterMethodChannel! private var inAppMessagingChannelHandler: CusomterIOInAppMessaging! + private var messagingPushChannelHandler: CustomerIOMessagingPush! private let logger: CioInternalCommon.Logger = DIGraphShared.shared.logger public static func register(with registrar: FlutterPluginRegistrar) { @@ -16,6 +17,7 @@ public class SwiftCustomerIoPlugin: NSObject, FlutterPlugin { registrar.addMethodCallDelegate(instance, channel: instance.methodChannel) instance.inAppMessagingChannelHandler = CusomterIOInAppMessaging(with: registrar) + instance.messagingPushChannelHandler = CustomerIOMessagingPush(with: registrar) } deinit { diff --git a/lib/customer_io_const.dart b/lib/customer_io_const.dart index e0d0d2f..d55a30a 100644 --- a/lib/customer_io_const.dart +++ b/lib/customer_io_const.dart @@ -12,6 +12,7 @@ class MethodConsts { static const String registerDeviceToken = "registerDeviceToken"; static const String onMessageReceived = "onMessageReceived"; static const String dismissMessage = "dismissMessage"; + static const String getRegisteredDeviceToken = "getRegisteredDeviceToken"; } class TrackingConsts { diff --git a/lib/messaging_push/method_channel.dart b/lib/messaging_push/method_channel.dart index ce8d5ad..29d6c54 100644 --- a/lib/messaging_push/method_channel.dart +++ b/lib/messaging_push/method_channel.dart @@ -14,6 +14,19 @@ class CustomerIOMessagingPushMethodChannel @visibleForTesting final methodChannel = const MethodChannel('customer_io_messaging_push'); + @override + Future getRegisteredDeviceToken() { + try { + return methodChannel + .invokeMethod(MethodConsts.getRegisteredDeviceToken) + .then((result) => result as String?); + } on PlatformException catch (exception) { + handleException(exception); + return Future.error( + exception.message ?? "Error fetching registered device token"); + } + } + @override Future onMessageReceived(Map message, {bool handleNotificationTrigger = true}) { diff --git a/lib/messaging_push/platform_interface.dart b/lib/messaging_push/platform_interface.dart index d3e1b0d..7c26929 100644 --- a/lib/messaging_push/platform_interface.dart +++ b/lib/messaging_push/platform_interface.dart @@ -24,6 +24,13 @@ abstract class CustomerIOMessagingPushPlatform extends PlatformInterface { _instance = instance; } + /// Method to get the device token registered with the Customer.io SDK. + /// Returns a [Future] that resolves to the device token registered with + /// Customer.io SDK. + Future getRegisteredDeviceToken() { + throw UnimplementedError('getRegisteredDeviceToken() has not been implemented.'); + } + /// Processes push notification received outside the CIO SDK. The method /// displays notification on device and tracks CIO metrics for push /// notification.