diff --git a/android/src/main/java/com/onesignal/flutter/OneSignalPlugin.java b/android/src/main/java/com/onesignal/flutter/OneSignalPlugin.java index a63622c7..aab440cc 100644 --- a/android/src/main/java/com/onesignal/flutter/OneSignalPlugin.java +++ b/android/src/main/java/com/onesignal/flutter/OneSignalPlugin.java @@ -7,6 +7,8 @@ import com.onesignal.OSEmailSubscriptionObserver; import com.onesignal.OSEmailSubscriptionStateChanges; import com.onesignal.OSInAppMessageAction; +import com.onesignal.OSInAppMessage; +import com.onesignal.OSInAppMessageLifecycleHandler; import com.onesignal.OSNotification; import com.onesignal.OSNotificationOpenedResult; import com.onesignal.OSNotificationReceivedEvent; @@ -57,6 +59,7 @@ public class OneSignalPlugin private boolean hasSetRequiresPrivacyConsent = false; private boolean waitingForUserPrivacyConsent = false; + private final HashMap notificationReceivedEventCache = new HashMap<>(); public OneSignalPlugin() { @@ -183,6 +186,7 @@ private void setAppId(MethodCall call, Result reply) { OneSignal.setInAppMessageClickHandler(this); OneSignal.initWithContext(context); OneSignal.setAppId(appId); + setInAppMessageLifecycleHandler(); if (hasSetRequiresPrivacyConsent && !OneSignal.userProvidedPrivacyConsent()) this.waitingForUserPrivacyConsent = true; @@ -409,6 +413,31 @@ public void inAppMessageClicked(OSInAppMessageAction action) { invokeMethodOnUiThread("OneSignal#handleClickedInAppMessage", OneSignalSerializer.convertInAppMessageClickedActionToMap(action)); } + /* in app message lifecycle */ + public void setInAppMessageLifecycleHandler() { + OneSignal.setInAppMessageLifecycleHandler(new OSInAppMessageLifecycleHandler() { + @Override + public void onWillDisplayInAppMessage(OSInAppMessage message) { + invokeMethodOnUiThread("OneSignal#onWillDisplayInAppMessage", OneSignalSerializer.convertInAppMessageToMap(message)); + } + + @Override + public void onDidDisplayInAppMessage(OSInAppMessage message) { + invokeMethodOnUiThread("OneSignal#onDidDisplayInAppMessage", OneSignalSerializer.convertInAppMessageToMap(message)); + } + + @Override + public void onWillDismissInAppMessage(OSInAppMessage message) { + invokeMethodOnUiThread("OneSignal#onWillDismissInAppMessage", OneSignalSerializer.convertInAppMessageToMap(message)); + } + + @Override + public void onDidDismissInAppMessage(OSInAppMessage message) { + invokeMethodOnUiThread("OneSignal#onDidDismissInAppMessage", OneSignalSerializer.convertInAppMessageToMap(message)); + } + }); + } + @Override public void notificationWillShowInForeground(OSNotificationReceivedEvent notificationReceivedEvent) { if (!this.hasSetNotificationWillShowInForegroundHandler) { diff --git a/android/src/main/java/com/onesignal/flutter/OneSignalSerializer.java b/android/src/main/java/com/onesignal/flutter/OneSignalSerializer.java index 24d36e2a..750a3628 100644 --- a/android/src/main/java/com/onesignal/flutter/OneSignalSerializer.java +++ b/android/src/main/java/com/onesignal/flutter/OneSignalSerializer.java @@ -6,6 +6,7 @@ import com.onesignal.OSEmailSubscriptionState; import com.onesignal.OSEmailSubscriptionStateChanges; import com.onesignal.OSInAppMessageAction; +import com.onesignal.OSInAppMessage; import com.onesignal.OSNotification; import com.onesignal.OSNotificationAction; import com.onesignal.OSNotificationOpenedResult; @@ -232,6 +233,14 @@ static HashMap convertInAppMessageClickedActionToMap(OSInAppMess return hash; } + static HashMap convertInAppMessageToMap(OSInAppMessage message) { + HashMap hash = new HashMap<>(); + + hash.put("message_id", message.getMessageId()); + + return hash; + } + static HashMap convertNotificationReceivedEventToMap(OSNotificationReceivedEvent notificationReceivedEvent) throws JSONException { return convertNotificationToMap(notificationReceivedEvent.getNotification()); } diff --git a/example/lib/main.dart b/example/lib/main.dart index 62c50cb8..49f801a3 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -83,6 +83,22 @@ class _MyAppState extends State { print("SMS SUBSCRIPTION STATE CHANGED ${changes.jsonRepresentation()}"); }); + OneSignal.shared.setOnWillDisplayInAppMessageHandler((message) { + print("ON WILL DISPLAY IN APP MESSAGE ${message.messageId}"); + }); + + OneSignal.shared.setOnDidDisplayInAppMessageHandler((message) { + print("ON DID DISPLAY IN APP MESSAGE ${message.messageId}"); + }); + + OneSignal.shared.setOnWillDismissInAppMessageHandler((message) { + print("ON WILL DISMISS IN APP MESSAGE ${message.messageId}"); + }); + + OneSignal.shared.setOnDidDismissInAppMessageHandler((message) { + print("ON DID DISMISS IN APP MESSAGE ${message.messageId}"); + }); + // NOTE: Replace with your own app ID from https://www.onesignal.com await OneSignal.shared .setAppId("380dc082-5231-4cc2-ab51-a03da5a0e4c2"); diff --git a/ios/Classes/OSFlutterCategories.h b/ios/Classes/OSFlutterCategories.h index 1b5a8df0..eba7a17b 100644 --- a/ios/Classes/OSFlutterCategories.h +++ b/ios/Classes/OSFlutterCategories.h @@ -43,6 +43,10 @@ - (NSDictionary *)toJson; @end +@interface OSInAppMessage (Flutter) +- (NSDictionary *)toJson; +@end + @interface NSError (Flutter) - (FlutterError *)flutterError; @end diff --git a/ios/Classes/OSFlutterCategories.m b/ios/Classes/OSFlutterCategories.m index 3781d7cb..b8a3bc49 100644 --- a/ios/Classes/OSFlutterCategories.m +++ b/ios/Classes/OSFlutterCategories.m @@ -97,6 +97,16 @@ - (NSDictionary *)toJson { } @end +@implementation OSInAppMessage (Flutter) +- (NSDictionary *)toJson { + NSMutableDictionary *json = [NSMutableDictionary new]; + + json[@"message_id"] = self.messageId; + + return json; +} +@end + @implementation NSError (Flutter) - (FlutterError *)flutterError { return [FlutterError errorWithCode:[NSString stringWithFormat:@"%i", (int)self.code] message:self.localizedDescription details:nil]; diff --git a/ios/Classes/OneSignalPlugin.h b/ios/Classes/OneSignalPlugin.h index 2d075914..d1feb00f 100644 --- a/ios/Classes/OneSignalPlugin.h +++ b/ios/Classes/OneSignalPlugin.h @@ -28,7 +28,7 @@ #import #import -@interface OneSignalPlugin : NSObject +@interface OneSignalPlugin : NSObject // Do NOT initialize instances of this class. // You must only reference the shared instance. diff --git a/ios/Classes/OneSignalPlugin.m b/ios/Classes/OneSignalPlugin.m index 756d084c..f883e93b 100644 --- a/ios/Classes/OneSignalPlugin.m +++ b/ios/Classes/OneSignalPlugin.m @@ -55,7 +55,6 @@ it will add the observers (ie. subscription) @property (strong, nonatomic) NSMutableDictionary* notificationCompletionCache; @property (strong, nonatomic) NSMutableDictionary* receivedNotificationCache; - @end @implementation OneSignalPlugin @@ -163,6 +162,8 @@ - (void)setAppId:(FlutterMethodCall *)call withResult:(FlutterResult)result { [OneSignal setAppId:call.arguments[@"appId"]]; + [OneSignal setInAppMessageLifecycleHandler: self]; + // If the user has required privacy consent, the SDK will not // add these observers. So we should delay adding the observers // until consent has been provided. @@ -399,6 +400,23 @@ - (void)handleInAppMessageClicked:(OSInAppMessageAction *)action { [self.channel invokeMethod:@"OneSignal#handleClickedInAppMessage" arguments:action.toJson]; } +#pragma mark OSInAppMessageLifeCycleHandler +- (void)onWillDisplayInAppMessage:(OSInAppMessage *) result { + [self.channel invokeMethod:@"OneSignal#onWillDisplayInAppMessage" arguments:result.toJson]; +} + +- (void)onDidDisplayInAppMessage:(OSInAppMessage *) result { + [self.channel invokeMethod:@"OneSignal#onDidDisplayInAppMessage" arguments:result.toJson]; +} + +- (void)onWillDismissInAppMessage:(OSInAppMessage *) result { + [self.channel invokeMethod:@"OneSignal#onWillDismissInAppMessage" arguments:result.toJson]; +} + +- (void)onDidDismissInAppMessage:(OSInAppMessage *) result { + [self.channel invokeMethod:@"OneSignal#onDidDismissInAppMessage" arguments:result.toJson]; +} + #pragma mark OSSubscriptionObserver - (void)onOSSubscriptionChanged:(OSSubscriptionStateChanges *)stateChanges { [self.channel invokeMethod:@"OneSignal#subscriptionChanged" arguments: stateChanges.toDictionary]; diff --git a/ios/onesignal_flutter.podspec b/ios/onesignal_flutter.podspec index fa7f9830..f79d5683 100644 --- a/ios/onesignal_flutter.podspec +++ b/ios/onesignal_flutter.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 'OneSignalXCFramework', '3.9.1' + s.dependency 'OneSignalXCFramework', '3.10.0' s.ios.deployment_target = '9.0' s.static_framework = true end diff --git a/lib/onesignal_flutter.dart b/lib/onesignal_flutter.dart index 0dd9e1b8..a1dadeb4 100644 --- a/lib/onesignal_flutter.dart +++ b/lib/onesignal_flutter.dart @@ -25,6 +25,10 @@ typedef void EmailSubscriptionChangeHandler(OSEmailSubscriptionStateChanges chan typedef void SMSSubscriptionChangeHandler(OSSMSSubscriptionStateChanges changes); typedef void PermissionChangeHandler(OSPermissionStateChanges changes); typedef void InAppMessageClickedHandler(OSInAppMessageAction action); +typedef void OnWillDisplayInAppMessageHandler(OSInAppMessage message); +typedef void OnDidDisplayInAppMessageHandler(OSInAppMessage message); +typedef void OnWillDismissInAppMessageHandler(OSInAppMessage message); +typedef void OnDidDismissInAppMessageHandler(OSInAppMessage message); typedef void NotificationWillShowInForegroundHandler(OSNotificationReceivedEvent event); class OneSignal { @@ -47,6 +51,10 @@ class OneSignal { SMSSubscriptionChangeHandler? _onSMSSubscriptionChangedHandler; PermissionChangeHandler? _onPermissionChangedHandler; InAppMessageClickedHandler? _onInAppMessageClickedHandler; + OnWillDisplayInAppMessageHandler? _onWillDisplayInAppMessageHandler; + OnDidDisplayInAppMessageHandler? _onDidDisplayInAppMessageHandler; + OnWillDismissInAppMessageHandler? _onWillDismissInAppMessageHandler; + OnDidDismissInAppMessageHandler? _onDidDismissInAppMessageHandler; NotificationWillShowInForegroundHandler? _onNotificationWillShowInForegroundHandler; // constructor method @@ -114,6 +122,34 @@ class OneSignal { _channel.invokeMethod("OneSignal#initInAppMessageClickedHandlerParams"); } + /// The in app message will display handler is called whenever the in app message + /// is about to be displayed + void setOnWillDisplayInAppMessageHandler( + OnWillDisplayInAppMessageHandler handler) { + _onWillDisplayInAppMessageHandler = handler; + } + + /// The in app message did display handler is called whenever the in app message + /// is displayed + void setOnDidDisplayInAppMessageHandler( + OnDidDisplayInAppMessageHandler handler) { + _onDidDisplayInAppMessageHandler = handler; + } + + /// The in app message will dismiss handler is called whenever the in app message + /// is about to be dismissed + void setOnWillDismissInAppMessageHandler( + OnWillDismissInAppMessageHandler handler) { + _onWillDismissInAppMessageHandler = handler; + } + + /// The in app message did dismiss handler is called whenever the in app message + /// is dismissed + void setOnDidDismissInAppMessageHandler( + OnDidDismissInAppMessageHandler handler) { + _onDidDismissInAppMessageHandler = handler; + } + /// The notification foreground handler is called whenever a notification arrives /// and the application is in foreground void setNotificationWillShowInForegroundHandler(NotificationWillShowInForegroundHandler handler) { @@ -428,6 +464,22 @@ class OneSignal { this._onInAppMessageClickedHandler != null) { this._onInAppMessageClickedHandler!( OSInAppMessageAction(call.arguments.cast())); + } else if (call.method == 'OneSignal#onWillDisplayInAppMessage' && + this._onWillDisplayInAppMessageHandler != null) { + this._onWillDisplayInAppMessageHandler!( + OSInAppMessage(call.arguments.cast())); + } else if (call.method == 'OneSignal#onDidDisplayInAppMessage' && + this._onDidDisplayInAppMessageHandler != null) { + this._onDidDisplayInAppMessageHandler!( + OSInAppMessage(call.arguments.cast())); + } else if (call.method == 'OneSignal#onWillDismissInAppMessage' && + this._onWillDismissInAppMessageHandler != null) { + this._onWillDismissInAppMessageHandler!( + OSInAppMessage(call.arguments.cast())); + } else if (call.method == 'OneSignal#onDidDismissInAppMessage' && + this._onDidDismissInAppMessageHandler != null) { + this._onDidDismissInAppMessageHandler!( + OSInAppMessage(call.arguments.cast())); } else if (call.method == 'OneSignal#handleNotificationWillShowInForeground' && this._onNotificationWillShowInForegroundHandler != null) { this._onNotificationWillShowInForegroundHandler!( diff --git a/lib/src/in_app_message.dart b/lib/src/in_app_message.dart index ac9967e6..1348c95e 100644 --- a/lib/src/in_app_message.dart +++ b/lib/src/in_app_message.dart @@ -34,3 +34,17 @@ class OSInAppMessageAction extends JSONStringRepresentable { } } + +class OSInAppMessage extends JSONStringRepresentable { + String? messageId; + + OSInAppMessage(Map json) { + this.messageId = json["message_id"]; + } + + String jsonRepresentation() { + return convertToJsonString({ + 'message_id': this.messageId + }); + } +}