Skip to content

Commit

Permalink
feat: in-app dismiss support (#51)
Browse files Browse the repository at this point in the history
  • Loading branch information
Shahroz16 authored Jun 1, 2023
1 parent 207229a commit c4d21f2
Show file tree
Hide file tree
Showing 14 changed files with 216 additions and 45 deletions.
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ android {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
// Customer.io SDK
def cioVersion = "[3.4.2,4.0)"
def cioVersion = "[3.5.0,4.0)"
implementation "io.customer.android:tracking:$cioVersion"
implementation "io.customer.android:messaging-push-fcm:$cioVersion"
implementation "io.customer.android:messaging-in-app:$cioVersion"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ 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.MessagingInAppModuleConfig
import io.customer.messaginginapp.ModuleMessagingInApp
Expand Down Expand Up @@ -42,7 +43,8 @@ class CustomerIoPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
private lateinit var flutterCommunicationChannel: MethodChannel
private lateinit var context: Context
private var activity: WeakReference<Activity>? = null
private lateinit var pushMessagingModule: CustomerIOPushMessaging

private lateinit var modules: List<CustomerIOPluginModule>

private val logger: Logger
get() = CustomerIOShared.instance().diStaticGraph.logger
Expand All @@ -68,8 +70,17 @@ class CustomerIoPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
flutterCommunicationChannel =
MethodChannel(flutterPluginBinding.binaryMessenger, "customer_io")
flutterCommunicationChannel.setMethodCallHandler(this)
pushMessagingModule = CustomerIOPushMessaging(flutterPluginBinding)
pushMessagingModule.onAttachedToEngine()

// Initialize modules
modules = listOf(
CustomerIOPushMessaging(flutterPluginBinding),
CustomerIOInAppMessaging(flutterPluginBinding)
)

// Attach modules to engine
modules.forEach {
it.onAttachedToEngine()
}
}

private fun MethodCall.toNativeMethodCall(
Expand Down Expand Up @@ -275,7 +286,10 @@ class CustomerIoPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {

override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
flutterCommunicationChannel.setMethodCallHandler(null)
pushMessagingModule.onDetachedFromEngine()

modules.forEach {
it.onDetachedFromEngine()
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ internal object Keys {
const val REGISTER_DEVICE_TOKEN = "registerDeviceToken"
const val TRACK_METRIC = "trackMetric"
const val ON_MESSAGE_RECEIVED = "onMessageReceived"
const val DISMISS_MESSAGE = "dismissMessage"
}

object Tracking {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package io.customer.customer_io.messaginginapp

import io.customer.customer_io.CustomerIOPluginModule
import io.customer.customer_io.constant.Keys
import io.customer.customer_io.invokeNative
import io.customer.messaginginapp.di.inAppMessaging
import io.customer.sdk.CustomerIO
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel

/**
* Flutter module implementation for messaging in-app module in native SDKs. All functionality
* linked with the module should be placed here.
*/
internal class CustomerIOInAppMessaging(
pluginBinding: FlutterPlugin.FlutterPluginBinding,
) : CustomerIOPluginModule, MethodChannel.MethodCallHandler {
override val moduleName: String = "InAppMessaging"
private val flutterCommunicationChannel: MethodChannel =
MethodChannel(pluginBinding.binaryMessenger, "customer_io_messaging_in_app")

override fun onAttachedToEngine() {
flutterCommunicationChannel.setMethodCallHandler(this)
}

override fun onDetachedFromEngine() {
flutterCommunicationChannel.setMethodCallHandler(null)
}

override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when (call.method) {
Keys.Methods.DISMISS_MESSAGE -> {
call.invokeNative(result) {
CustomerIO.instance().inAppMessaging().dismissMessage()
}
}

else -> {
result.notImplemented()
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ internal class CustomerIOPushMessaging(
)
}
}

else -> {
result.notImplemented()
}
Expand Down
38 changes: 38 additions & 0 deletions ios/Classes/CustomerIOInAppMessaging.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import Foundation
import Flutter
import CioMessagingInApp

public class CusomterIOInAppMessaging: NSObject, FlutterPlugin {

private var methodChannel: FlutterMethodChannel!

public static func register(with registrar: FlutterPluginRegistrar) {
}

init(with registrar: FlutterPluginRegistrar) {
super.init()

methodChannel = FlutterMethodChannel(name: "customer_io_messaging_in_app", binaryMessenger: registrar.messenger())
registrar.addMethodCallDelegate(self, channel: methodChannel)
}


deinit {
methodChannel.setMethodCallHandler(nil)
}

public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
// Handle method calls for this method channel
switch(call.method) {
case Keys.Methods.dismissMessage:
MessagingInApp.shared.dismissMessage()
default:
result(FlutterMethodNotImplemented)
}
}

func detachFromEngine() {
methodChannel.setMethodCallHandler(nil)
methodChannel = nil
}
}
2 changes: 1 addition & 1 deletion ios/Classes/Keys.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ struct Keys {
static let setProfileAttributes = "setProfileAttributes"
static let registerDeviceToken = "registerDeviceToken"
static let trackMetric = "trackMetric"

static let dismissMessage = "dismissMessage"
}

struct Tracking {
Expand Down
78 changes: 41 additions & 37 deletions ios/Classes/SwiftCustomerIoPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,59 +7,63 @@ import CioMessagingInApp
public class SwiftCustomerIoPlugin: NSObject, FlutterPlugin {

private var methodChannel: FlutterMethodChannel!
private var inAppMessagingChannelHandler: CusomterIOInAppMessaging!

public static func register(with registrar: FlutterPluginRegistrar) {
let instance = SwiftCustomerIoPlugin()
instance.methodChannel = FlutterMethodChannel(name: "customer_io", binaryMessenger: registrar.messenger())
registrar.addMethodCallDelegate(instance, channel: instance.methodChannel)

instance.inAppMessagingChannelHandler = CusomterIOInAppMessaging(with: registrar)
}

deinit {
self.methodChannel.setMethodCallHandler(nil)
self.inAppMessagingChannelHandler.detachFromEngine()
}

public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch(call.method) {
case Keys.Methods.initialize:
call.toNativeMethodCall(
result: result) {
initialize(params: $0)
case Keys.Methods.initialize:
call.toNativeMethodCall(
result: result) {
initialize(params: $0)
}
case Keys.Methods.clearIdentify:
clearIdentify()
case Keys.Methods.track:
call.toNativeMethodCall(
result: result) {
track(params: $0)
}
case Keys.Methods.screen:
call.toNativeMethodCall(
result: result) {
screen(params: $0)
}
case Keys.Methods.identify:
call.toNativeMethodCall(
result: result) {
identify(params: $0)
}
case Keys.Methods.setProfileAttributes:
call.toNativeMethodCall(result: result) {
setProfileAttributes(params: $0)
}
case Keys.Methods.clearIdentify:
clearIdentify()
case Keys.Methods.track:
call.toNativeMethodCall(
result: result) {
track(params: $0)
case Keys.Methods.setDeviceAttributes:
call.toNativeMethodCall(result: result) {
setDeviceAttributes(params: $0)
}
case Keys.Methods.screen:
call.toNativeMethodCall(
result: result) {
screen(params: $0)
case Keys.Methods.registerDeviceToken:
call.toNativeMethodCall(result: result) {
registerDeviceToken(params: $0)
}
case Keys.Methods.identify:
call.toNativeMethodCall(
result: result) {
identify(params: $0)
case Keys.Methods.trackMetric:
call.toNativeMethodCall(result: result) {
trackMetric(params: $0)
}
case Keys.Methods.setProfileAttributes:
call.toNativeMethodCall(result: result) {
setProfileAttributes(params: $0)
}
case Keys.Methods.setDeviceAttributes:
call.toNativeMethodCall(result: result) {
setDeviceAttributes(params: $0)
}
case Keys.Methods.registerDeviceToken:
call.toNativeMethodCall(result: result) {
registerDeviceToken(params: $0)
}
case Keys.Methods.trackMetric:
call.toNativeMethodCall(result: result) {
trackMetric(params: $0)
}
default:
result(FlutterMethodNotImplemented)
default:
result(FlutterMethodNotImplemented)
}
}

Expand Down Expand Up @@ -165,7 +169,7 @@ public class SwiftCustomerIoPlugin: NSObject, FlutterPlugin {
config.modify(params: params)
}


if let enableInApp = params[Keys.Environment.enableInApp] as? Bool {
if enableInApp{
initializeInApp()
Expand Down
2 changes: 1 addition & 1 deletion ios/customer_io.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#
Pod::Spec.new do |s|
s.name = 'customer_io'
s.version = '1.1.2'
s.version = '1.2.0'
s.summary = 'Customer.io plugin for Flutter'
s.homepage = 'https://customer.io/'
s.license = { :file => '../LICENSE' }
Expand Down
8 changes: 8 additions & 0 deletions lib/customer_io.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'customer_io_config.dart';
import 'customer_io_enums.dart';
import 'customer_io_inapp.dart';
import 'customer_io_platform_interface.dart';
import 'messaging_in_app/platform_interface.dart';
import 'messaging_push/platform_interface.dart';

class CustomerIO {
Expand All @@ -14,6 +15,9 @@ class CustomerIO {
static CustomerIOMessagingPushPlatform get _customerIOMessagingPush =>
CustomerIOMessagingPushPlatform.instance;

static CustomerIOMessagingInAppPlatform get _customerIOMessagingInApp =>
CustomerIOMessagingInAppPlatform.instance;

/// To initialize the plugin
///
/// @param config includes required and optional configs etc
Expand Down Expand Up @@ -108,4 +112,8 @@ class CustomerIO {
static CustomerIOMessagingPushPlatform messagingPush() {
return _customerIOMessagingPush;
}

static CustomerIOMessagingInAppPlatform messagingInApp() {
return _customerIOMessagingInApp;
}
}
1 change: 1 addition & 0 deletions lib/customer_io_const.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class MethodConsts {
static const String setProfileAttributes = "setProfileAttributes";
static const String registerDeviceToken = "registerDeviceToken";
static const String onMessageReceived = "onMessageReceived";
static const String dismissMessage = "dismissMessage";
}

class TrackingConsts {
Expand Down
2 changes: 1 addition & 1 deletion lib/customer_io_plugin_version.dart
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// Don't modify this line - it's automatically updated
const version = "1.1.2";
const version = "1.2.0";
29 changes: 29 additions & 0 deletions lib/messaging_in_app/method_channel.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';

import '../customer_io_const.dart';
import 'platform_interface.dart';

/// An implementation of [CustomerIOMessagingInAppPlatform] that uses method
/// channels.
class CustomerIOMessagingInAppMethodChannel
extends CustomerIOMessagingInAppPlatform {
/// The method channel used to interact with the native platform.
@visibleForTesting
final methodChannel = const MethodChannel('customer_io_messaging_in_app');

@override
void dismissMessage() async {
try {
methodChannel.invokeMethod(MethodConsts.dismissMessage);
} on PlatformException catch (e) {
handleException(e);
}
}

void handleException(PlatformException exception) {
if (kDebugMode) {
print(exception);
}
}
}
30 changes: 30 additions & 0 deletions lib/messaging_in_app/platform_interface.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import 'package:plugin_platform_interface/plugin_platform_interface.dart';

import 'method_channel.dart';

/// The default instance of [CustomerIOMessagingInAppPlatform] to use
///
/// Platform-specific plugins should override this with their own
/// platform-specific class that extends [CustomerIOMessagingInAppPlatform]
/// when they register themselves.
///
/// Defaults to [CustomerIOMessagingInAppMethodChannel]
abstract class CustomerIOMessagingInAppPlatform extends PlatformInterface {
CustomerIOMessagingInAppPlatform() : super(token: _token);

static final Object _token = Object();

static CustomerIOMessagingInAppPlatform _instance =
CustomerIOMessagingInAppMethodChannel();

static CustomerIOMessagingInAppPlatform get instance => _instance;

static set instance(CustomerIOMessagingInAppPlatform instance) {
PlatformInterface.verifyToken(instance, _token);
_instance = instance;
}

void dismissMessage() {
throw UnimplementedError('dismissMessage() has not been implemented.');
}
}

0 comments on commit c4d21f2

Please sign in to comment.