From bd03be8dc5ff90de403c588a971a018e0139b10c Mon Sep 17 00:00:00 2001 From: Shahroz Khan Date: Mon, 25 Nov 2024 12:59:45 +0500 Subject: [PATCH] chore: added in-app event listeners (#180) --- .../customer_io/CustomerIOPluginModule.kt | 15 ++- .../customer/customer_io/CustomerIoPlugin.kt | 90 +++++--------- .../CustomerIOInAppMessaging.kt | 115 ++++++++++++++---- .../messagingpush/CustomerIOPushMessaging.kt | 56 ++++----- .../lib/src/screens/dashboard.dart | 2 +- ios/Classes/SwiftCustomerIoPlugin.swift | 5 + lib/customer_io.dart | 12 -- lib/customer_io_method_channel.dart | 45 ------- lib/customer_io_platform_interface.dart | 7 -- lib/messaging_in_app/method_channel.dart | 46 +++++++ lib/messaging_in_app/platform_interface.dart | 9 ++ test/customer_io_test.mocks.dart | 1 - 12 files changed, 221 insertions(+), 182 deletions(-) diff --git a/android/src/main/kotlin/io/customer/customer_io/CustomerIOPluginModule.kt b/android/src/main/kotlin/io/customer/customer_io/CustomerIOPluginModule.kt index 403a339..ebf0482 100644 --- a/android/src/main/kotlin/io/customer/customer_io/CustomerIOPluginModule.kt +++ b/android/src/main/kotlin/io/customer/customer_io/CustomerIOPluginModule.kt @@ -1,6 +1,9 @@ package io.customer.customer_io +import io.customer.sdk.CustomerIOBuilder import io.flutter.embedding.engine.plugins.FlutterPlugin +import io.flutter.embedding.engine.plugins.activity.ActivityAware +import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding import io.flutter.plugin.common.MethodChannel /** @@ -8,7 +11,7 @@ import io.flutter.plugin.common.MethodChannel * should be treated as module in Flutter SDK and should be used to hold all relevant methods at * single place. */ -internal interface CustomerIOPluginModule : MethodChannel.MethodCallHandler { +internal interface CustomerIOPluginModule : MethodChannel.MethodCallHandler, ActivityAware { /** * Unique name of module to identify between other modules */ @@ -36,4 +39,14 @@ internal interface CustomerIOPluginModule : MethodChannel.MethodCallHandler { fun onDetachedFromEngine() { flutterCommunicationChannel.setMethodCallHandler(null) } + + fun configureModule(builder: CustomerIOBuilder, config: Map) + + override fun onDetachedFromActivity() {} + + override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {} + + override fun onDetachedFromActivityForConfigChanges() {} + + override fun onAttachedToActivity(binding: ActivityPluginBinding) {} } diff --git a/android/src/main/kotlin/io/customer/customer_io/CustomerIoPlugin.kt b/android/src/main/kotlin/io/customer/customer_io/CustomerIoPlugin.kt index 1a0f400..399a387 100644 --- a/android/src/main/kotlin/io/customer/customer_io/CustomerIoPlugin.kt +++ b/android/src/main/kotlin/io/customer/customer_io/CustomerIoPlugin.kt @@ -1,14 +1,11 @@ package io.customer.customer_io -import android.app.Activity import android.app.Application import android.content.Context import androidx.annotation.NonNull import io.customer.customer_io.constant.Keys import io.customer.customer_io.messaginginapp.CustomerIOInAppMessaging import io.customer.customer_io.messagingpush.CustomerIOPushMessaging -import io.customer.messaginginapp.type.InAppEventListener -import io.customer.messaginginapp.type.InAppMessage import io.customer.sdk.CustomerIO import io.customer.sdk.CustomerIOBuilder import io.customer.sdk.core.di.SDKComponent @@ -24,7 +21,6 @@ import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel.MethodCallHandler import io.flutter.plugin.common.MethodChannel.Result -import java.lang.ref.WeakReference /** * Android implementation of plugin that will let Flutter developers to @@ -37,28 +33,11 @@ class CustomerIoPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { /// when the Flutter Engine is detached from the Activity private lateinit var flutterCommunicationChannel: MethodChannel private lateinit var context: Context - private var activity: WeakReference? = null private lateinit var modules: List private val logger: Logger = SDKComponent.logger - override fun onAttachedToActivity(binding: ActivityPluginBinding) { - this.activity = WeakReference(binding.activity) - } - - override fun onDetachedFromActivityForConfigChanges() { - onDetachedFromActivity() - } - - override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) { - onAttachedToActivity(binding) - } - - override fun onDetachedFromActivity() { - this.activity = null - } - override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { context = flutterPluginBinding.applicationContext flutterCommunicationChannel = @@ -276,18 +255,21 @@ class CustomerIoPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { args.getAsTypeOrNull("cdnHost")?.let(::cdnHost) // Configure in-app messaging module based on config provided by customer app args.getAsTypeOrNull>(key = "inApp")?.let { inAppConfig -> - CustomerIOInAppMessaging.addNativeModuleFromConfig( - builder = this, - config = inAppConfig, - region = givenRegion - ) + modules.filterIsInstance().forEach { + it.configureModule( + builder = this, + config = inAppConfig.plus("region" to givenRegion), + ) + } } // Configure push messaging module based on config provided by customer app args.getAsTypeOrNull>(key = "push").let { pushConfig -> - CustomerIOPushMessaging.addNativeModuleFromConfig( - builder = this, - config = pushConfig ?: emptyMap() - ) + modules.filterIsInstance().forEach { + it.configureModule( + builder = this, + config = pushConfig ?: emptyMap() + ) + } } }.build() @@ -303,44 +285,28 @@ class CustomerIoPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { it.onDetachedFromEngine() } } -} -class CustomerIOInAppEventListener(private val invokeMethod: (String, Any?) -> Unit) : - InAppEventListener { - override fun errorWithMessage(message: InAppMessage) { - invokeMethod( - "errorWithMessage", mapOf( - "messageId" to message.messageId, "deliveryId" to message.deliveryId - ) - ) + override fun onAttachedToActivity(binding: ActivityPluginBinding) { + modules.forEach { + it.onAttachedToActivity(binding) + } } - override fun messageActionTaken( - message: InAppMessage, actionValue: String, actionName: String - ) { - invokeMethod( - "messageActionTaken", mapOf( - "messageId" to message.messageId, - "deliveryId" to message.deliveryId, - "actionValue" to actionValue, - "actionName" to actionName - ) - ) + override fun onDetachedFromActivityForConfigChanges() { + modules.forEach { + it.onDetachedFromActivityForConfigChanges() + } } - override fun messageDismissed(message: InAppMessage) { - invokeMethod( - "messageDismissed", mapOf( - "messageId" to message.messageId, "deliveryId" to message.deliveryId - ) - ) + override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) { + modules.forEach { + it.onReattachedToActivityForConfigChanges(binding) + } } - override fun messageShown(message: InAppMessage) { - invokeMethod( - "messageShown", mapOf( - "messageId" to message.messageId, "deliveryId" to message.deliveryId - ) - ) + override fun onDetachedFromActivity() { + modules.forEach { + it.onDetachedFromActivity() + } } } diff --git a/android/src/main/kotlin/io/customer/customer_io/messaginginapp/CustomerIOInAppMessaging.kt b/android/src/main/kotlin/io/customer/customer_io/messaginginapp/CustomerIOInAppMessaging.kt index afb8b3e..5603003 100644 --- a/android/src/main/kotlin/io/customer/customer_io/messaginginapp/CustomerIOInAppMessaging.kt +++ b/android/src/main/kotlin/io/customer/customer_io/messaginginapp/CustomerIOInAppMessaging.kt @@ -1,5 +1,6 @@ package io.customer.customer_io.messaginginapp +import android.app.Activity import io.customer.customer_io.CustomerIOPluginModule import io.customer.customer_io.constant.Keys import io.customer.customer_io.getAsTypeOrNull @@ -7,13 +8,18 @@ import io.customer.customer_io.invokeNative import io.customer.messaginginapp.MessagingInAppModuleConfig import io.customer.messaginginapp.ModuleMessagingInApp import io.customer.messaginginapp.di.inAppMessaging +import io.customer.messaginginapp.type.InAppEventListener +import io.customer.messaginginapp.type.InAppMessage import io.customer.sdk.CustomerIO import io.customer.sdk.CustomerIOBuilder import io.customer.sdk.core.di.SDKComponent import io.customer.sdk.data.model.Region import io.flutter.embedding.engine.plugins.FlutterPlugin +import io.flutter.embedding.engine.plugins.activity.ActivityAware +import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel +import java.lang.ref.WeakReference /** * Flutter module implementation for messaging in-app module in native SDKs. All functionality @@ -21,10 +27,27 @@ import io.flutter.plugin.common.MethodChannel */ internal class CustomerIOInAppMessaging( pluginBinding: FlutterPlugin.FlutterPluginBinding, -) : CustomerIOPluginModule, MethodChannel.MethodCallHandler { +) : CustomerIOPluginModule, MethodChannel.MethodCallHandler, ActivityAware { override val moduleName: String = "InAppMessaging" override val flutterCommunicationChannel: MethodChannel = MethodChannel(pluginBinding.binaryMessenger, "customer_io_messaging_in_app") + private var activity: WeakReference? = null + + override fun onAttachedToActivity(binding: ActivityPluginBinding) { + this.activity = WeakReference(binding.activity) + } + + override fun onDetachedFromActivityForConfigChanges() { + onDetachedFromActivity() + } + + override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) { + onAttachedToActivity(binding) + } + + override fun onDetachedFromActivity() { + this.activity = null + } override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { when (call.method) { @@ -40,30 +63,74 @@ internal class CustomerIOInAppMessaging( } } - companion object { - /** - * Adds in-app module to native Android SDK based on the configuration provided by - * customer app. - * - * @param builder instance of CustomerIOBuilder to add push messaging module. - * @param config configuration provided by customer app for in-app messaging module. - * @param region region of the customer app. - */ - internal fun addNativeModuleFromConfig( - builder: CustomerIOBuilder, - config: Map, - region: Region - ) { - val siteId = config.getAsTypeOrNull("siteId") - if (siteId.isNullOrBlank()) { - SDKComponent.logger.error("Site ID is required to initialize InAppMessaging module") - return - } - val module = ModuleMessagingInApp( - MessagingInAppModuleConfig.Builder(siteId = siteId, region = region).build(), - ) - builder.addCustomerIOModule(module) + /** + * Adds in-app module to native Android SDK based on the configuration provided by + * customer app. + * + * @param builder instance of CustomerIOBuilder to add push messaging module. + * @param config configuration provided by customer app for in-app messaging module. + */ + override fun configureModule( + builder: CustomerIOBuilder, + config: Map + ) { + val siteId = config.getAsTypeOrNull("siteId") + val regionRawValue = config.getAsTypeOrNull("region") + val givenRegion = regionRawValue.let { Region.getRegion(it) } + + if (siteId.isNullOrBlank()) { + SDKComponent.logger.error("Site ID is required to initialize InAppMessaging module") + return } + val module = ModuleMessagingInApp( + MessagingInAppModuleConfig.Builder(siteId = siteId, region = givenRegion) + .setEventListener(CustomerIOInAppEventListener { method, args -> + this.activity?.get()?.runOnUiThread { + flutterCommunicationChannel.invokeMethod(method, args) + } + }) + .build(), + ) + builder.addCustomerIOModule(module) } +} +class CustomerIOInAppEventListener(private val invokeMethod: (String, Any?) -> Unit) : + InAppEventListener { + override fun errorWithMessage(message: InAppMessage) { + invokeMethod( + "errorWithMessage", mapOf( + "messageId" to message.messageId, "deliveryId" to message.deliveryId + ) + ) + } + + override fun messageActionTaken( + message: InAppMessage, actionValue: String, actionName: String + ) { + invokeMethod( + "messageActionTaken", mapOf( + "messageId" to message.messageId, + "deliveryId" to message.deliveryId, + "actionValue" to actionValue, + "actionName" to actionName + ) + ) + } + + override fun messageDismissed(message: InAppMessage) { + invokeMethod( + "messageDismissed", mapOf( + "messageId" to message.messageId, "deliveryId" to message.deliveryId + ) + ) + } + + override fun messageShown(message: InAppMessage) { + invokeMethod( + "messageShown", mapOf( + "messageId" to message.messageId, "deliveryId" to message.deliveryId + ) + ) + } } \ No newline at end of file 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 0e6c560..f625be8 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 @@ -88,36 +88,34 @@ internal class CustomerIOPushMessaging( } } - companion object { - /** - * Adds push messaging module to native Android SDK based on the configuration provided by - * customer app. - * - * @param builder instance of CustomerIOBuilder to add push messaging module. - * @param config configuration provided by customer app for push messaging module. - */ - internal fun addNativeModuleFromConfig( - builder: CustomerIOBuilder, - config: Map - ) { - val androidConfig = - config.getAsTypeOrNull>(key = "android") ?: emptyMap() - // Prefer `android` object for push configurations as it's more specific to Android - // For common push configurations, use `config` object instead of `android` + /** + * Adds push messaging module to native Android SDK based on the configuration provided by + * customer app. + * + * @param builder instance of CustomerIOBuilder to add push messaging module. + * @param config configuration provided by customer app for push messaging module. + */ + override fun configureModule( + builder: CustomerIOBuilder, + config: Map + ) { + val androidConfig = + config.getAsTypeOrNull>(key = "android") ?: emptyMap() + // Prefer `android` object for push configurations as it's more specific to Android + // For common push configurations, use `config` object instead of `android` - // Default push click behavior is to prevent restart of activity in Flutter apps - val pushClickBehavior = androidConfig.getAsTypeOrNull("pushClickBehavior") - ?.takeIf { it.isNotBlank() } - ?.let { value -> - runCatching { enumValueOf(value) }.getOrNull() - } ?: PushClickBehavior.ACTIVITY_PREVENT_RESTART + // Default push click behavior is to prevent restart of activity in Flutter apps + val pushClickBehavior = androidConfig.getAsTypeOrNull("pushClickBehavior") + ?.takeIf { it.isNotBlank() } + ?.let { value -> + runCatching { enumValueOf(value) }.getOrNull() + } ?: PushClickBehavior.ACTIVITY_PREVENT_RESTART - val module = ModuleMessagingPushFCM( - moduleConfig = MessagingPushModuleConfig.Builder().apply { - setPushClickBehavior(pushClickBehavior = pushClickBehavior) - }.build(), - ) - builder.addCustomerIOModule(module) - } + val module = ModuleMessagingPushFCM( + moduleConfig = MessagingPushModuleConfig.Builder().apply { + setPushClickBehavior(pushClickBehavior = pushClickBehavior) + }.build(), + ) + builder.addCustomerIOModule(module) } } diff --git a/apps/amiapp_flutter/lib/src/screens/dashboard.dart b/apps/amiapp_flutter/lib/src/screens/dashboard.dart index 5b4308f..0c32a00 100644 --- a/apps/amiapp_flutter/lib/src/screens/dashboard.dart +++ b/apps/amiapp_flutter/lib/src/screens/dashboard.dart @@ -54,7 +54,7 @@ class _DashboardScreenState extends State { .then((value) => setState(() => _buildInfo = value)); inAppMessageStreamSubscription = - CustomerIO.instance.subscribeToInAppEventListener(handleInAppEvent); + CustomerIO.instance.inAppMessaging.subscribeToInAppEventListener(handleInAppEvent); // Setup 3rd party SDK, flutter-fire. // We install this SDK into sample app to make sure the CIO SDK behaves as expected when there is another SDK installed that handles push notifications. diff --git a/ios/Classes/SwiftCustomerIoPlugin.swift b/ios/Classes/SwiftCustomerIoPlugin.swift index 00dafae..f8363c1 100644 --- a/ios/Classes/SwiftCustomerIoPlugin.swift +++ b/ios/Classes/SwiftCustomerIoPlugin.swift @@ -179,6 +179,11 @@ public class SwiftCustomerIoPlugin: NSObject, FlutterPlugin { if let inAppConfig = try? MessagingInAppConfigBuilder.build(from: params) { MessagingInApp.initialize(withConfig: inAppConfig) + MessagingInApp.shared.setEventListener(CustomerIOInAppEventListener( + invokeMethod: {method,args in + self.invokeMethod(method, args) + }) + ) } // TODO: Initialize in-app module with given config diff --git a/lib/customer_io.dart b/lib/customer_io.dart index 5ed4376..a231ae8 100644 --- a/lib/customer_io.dart +++ b/lib/customer_io.dart @@ -5,7 +5,6 @@ import 'package:flutter/cupertino.dart'; import 'customer_io_config.dart'; import 'customer_io_enums.dart'; -import 'customer_io_inapp.dart'; import 'customer_io_platform_interface.dart'; import 'extensions/map_extensions.dart'; import 'messaging_in_app/platform_interface.dart'; @@ -162,15 +161,4 @@ class CustomerIO { return _platform.setProfileAttributes( attributes: attributes.excludeNullValues()); } - - /// Subscribes to an in-app event listener. - /// - /// [onEvent] - A callback function that will be called every time an in-app event occurs. - /// The callback returns [InAppEvent]. - /// - /// Returns a [StreamSubscription] that can be used to subscribe/unsubscribe from the event listener. - StreamSubscription subscribeToInAppEventListener( - void Function(InAppEvent) onEvent) { - return _platform.subscribeToInAppEventListener(onEvent); - } } diff --git a/lib/customer_io_method_channel.dart b/lib/customer_io_method_channel.dart index 463e8ab..5a303c0 100644 --- a/lib/customer_io_method_channel.dart +++ b/lib/customer_io_method_channel.dart @@ -6,7 +6,6 @@ import 'package:flutter/services.dart'; import 'customer_io_config.dart'; import 'customer_io_const.dart'; -import 'customer_io_inapp.dart'; import 'customer_io_platform_interface.dart'; /// An implementation of [CustomerIOPlatform] that uses method channels. @@ -15,50 +14,6 @@ class CustomerIOMethodChannel extends CustomerIOPlatform { @visibleForTesting final methodChannel = const MethodChannel('customer_io'); - final _inAppEventStreamController = StreamController.broadcast(); - - CustomerIOMethodChannel() { - methodChannel.setMethodCallHandler(_onMethodCall); - } - - /// Method to subscribe to the In-App event listener. - /// - /// The `onEvent` function will be called whenever an In-App event occurs. - /// Returns a [StreamSubscription] object that can be used to unsubscribe from the stream. - @override - StreamSubscription subscribeToInAppEventListener( - void Function(InAppEvent) onEvent) { - StreamSubscription subscription = - _inAppEventStreamController.stream.listen(onEvent); - return subscription; - } - - /// Method call handler to handle events from native bindings - Future _onMethodCall(MethodCall call) async { - /// Cast the arguments to a map of strings to dynamic values. - final arguments = - (call.arguments as Map).cast(); - - switch (call.method) { - case "messageShown": - _inAppEventStreamController - .add(InAppEvent.fromMap(EventType.messageShown, arguments)); - break; - case "messageDismissed": - _inAppEventStreamController - .add(InAppEvent.fromMap(EventType.messageDismissed, arguments)); - break; - case "errorWithMessage": - _inAppEventStreamController - .add(InAppEvent.fromMap(EventType.errorWithMessage, arguments)); - break; - case "messageActionTaken": - _inAppEventStreamController - .add(InAppEvent.fromMap(EventType.messageActionTaken, arguments)); - break; - } - } - /// To initialize the plugin @override Future initialize({ diff --git a/lib/customer_io_platform_interface.dart b/lib/customer_io_platform_interface.dart index a7bd11f..c9646b5 100644 --- a/lib/customer_io_platform_interface.dart +++ b/lib/customer_io_platform_interface.dart @@ -4,7 +4,6 @@ import 'package:customer_io/customer_io_config.dart'; import 'package:customer_io/customer_io_enums.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; -import 'customer_io_inapp.dart'; import 'customer_io_method_channel.dart'; /// The default instance of [CustomerIOPlatform] to use @@ -73,10 +72,4 @@ abstract class CustomerIOPlatform extends PlatformInterface { throw UnimplementedError( 'setProfileAttributes() has not been implemented.'); } - - StreamSubscription subscribeToInAppEventListener( - void Function(InAppEvent) onEvent) { - throw UnimplementedError( - 'subscribeToInAppEventListener() has not been implemented.'); - } } diff --git a/lib/messaging_in_app/method_channel.dart b/lib/messaging_in_app/method_channel.dart index cd5a046..2f32c06 100644 --- a/lib/messaging_in_app/method_channel.dart +++ b/lib/messaging_in_app/method_channel.dart @@ -1,7 +1,10 @@ +import 'dart:async'; + import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import '../customer_io_const.dart'; +import '../customer_io_inapp.dart'; import 'platform_interface.dart'; /// An implementation of [CustomerIOMessagingInAppPlatform] that uses method @@ -11,6 +14,7 @@ class CustomerIOMessagingInAppMethodChannel /// The method channel used to interact with the native platform. @visibleForTesting final methodChannel = const MethodChannel('customer_io_messaging_in_app'); + final _inAppEventStreamController = StreamController.broadcast(); @override void dismissMessage() async { @@ -21,6 +25,48 @@ class CustomerIOMessagingInAppMethodChannel } } + /// Method to subscribe to the In-App event listener. + /// + /// The `onEvent` function will be called whenever an In-App event occurs. + /// Returns a [StreamSubscription] object that can be used to unsubscribe from the stream. + @override + StreamSubscription subscribeToInAppEventListener( + void Function(InAppEvent) onEvent) { + StreamSubscription subscription = + _inAppEventStreamController.stream.listen(onEvent); + return subscription; + } + + CustomerIOMessagingInAppMethodChannel() { + methodChannel.setMethodCallHandler(_onMethodCall); + } + + /// Method call handler to handle events from native bindings + Future _onMethodCall(MethodCall call) async { + /// Cast the arguments to a map of strings to dynamic values. + final arguments = + (call.arguments as Map).cast(); + + switch (call.method) { + case "messageShown": + _inAppEventStreamController + .add(InAppEvent.fromMap(EventType.messageShown, arguments)); + break; + case "messageDismissed": + _inAppEventStreamController + .add(InAppEvent.fromMap(EventType.messageDismissed, arguments)); + break; + case "errorWithMessage": + _inAppEventStreamController + .add(InAppEvent.fromMap(EventType.errorWithMessage, arguments)); + break; + case "messageActionTaken": + _inAppEventStreamController + .add(InAppEvent.fromMap(EventType.messageActionTaken, arguments)); + break; + } + } + void handleException(PlatformException exception) { if (kDebugMode) { print(exception); diff --git a/lib/messaging_in_app/platform_interface.dart b/lib/messaging_in_app/platform_interface.dart index b05daf7..d123ac0 100644 --- a/lib/messaging_in_app/platform_interface.dart +++ b/lib/messaging_in_app/platform_interface.dart @@ -1,5 +1,8 @@ +import 'dart:async'; + import 'package:plugin_platform_interface/plugin_platform_interface.dart'; +import '../customer_io_inapp.dart'; import 'method_channel.dart'; /// The default instance of [CustomerIOMessagingInAppPlatform] to use @@ -27,4 +30,10 @@ abstract class CustomerIOMessagingInAppPlatform extends PlatformInterface { void dismissMessage() { throw UnimplementedError('dismissMessage() has not been implemented.'); } + + StreamSubscription subscribeToInAppEventListener( + void Function(InAppEvent) onEvent) { + throw UnimplementedError( + 'subscribeToInAppEventListener() has not been implemented.'); + } } diff --git a/test/customer_io_test.mocks.dart b/test/customer_io_test.mocks.dart index dd87c9f..4a35717 100644 --- a/test/customer_io_test.mocks.dart +++ b/test/customer_io_test.mocks.dart @@ -158,7 +158,6 @@ class MockTestCustomerIoPlatform extends _i1.Mock ), returnValueForMissingStub: null, ); - @override _i2.StreamSubscription subscribeToInAppEventListener( void Function(_i6.InAppEvent)? onEvent) => (super.noSuchMethod(