Skip to content

Commit 9b08b21

Browse files
committed
Update Notification Will Display Events
the willShowInForegroundHandler is now the OneSsignalNotificationLifecycleListener which has the onWillDisplay function.
1 parent 924bb48 commit 9b08b21

File tree

9 files changed

+144
-137
lines changed

9 files changed

+144
-137
lines changed

android/src/main/java/com/onesignal/flutter/OneSignalNotifications.java

Lines changed: 25 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,8 @@
3737
import io.flutter.plugin.common.PluginRegistry;
3838
import io.flutter.plugin.common.PluginRegistry.Registrar;
3939

40-
public class OneSignalNotifications extends FlutterRegistrarResponder implements MethodCallHandler, INotificationClickHandler, INotificationWillShowInForegroundHandler, IPermissionObserver {
41-
private boolean hasSetNotificationWillShowInForegroundHandler = false;
42-
private final HashMap<String, INotificationReceivedEvent> notificationReceivedEventCache = new HashMap<>();
40+
public class OneSignalNotifications extends FlutterRegistrarResponder implements MethodCallHandler, INotificationClickHandler, INotificationLifecycleListener, IPermissionObserver {
41+
private final HashMap<String, INotificationReceivedEvent> notificationOnWillDisplayEventCache = new HashMap<>();
4342

4443
static void registerWith(BinaryMessenger messenger) {
4544
OneSignalNotifications controller = new OneSignalNotifications();
@@ -62,10 +61,10 @@ else if (call.method.contentEquals("OneSignal#clearAll"))
6261
this.clearAll(call, result);
6362
else if (call.method.contentEquals("OneSignal#initNotificationOpenedHandlerParams"))
6463
this.initNotificationOpenedHandlerParams(call, result);
65-
else if (call.method.contentEquals("OneSignal#initNotificationWillShowInForegroundHandlerParams"))
66-
this.initNotificationWillShowInForegroundHandlerParams();
67-
else if (call.method.contentEquals("OneSignal#completeNotification"))
68-
this.completeNotification(call, result);
64+
else if (call.method.contentEquals("OneSignal#displayNotification"))
65+
this.displayNotification(call, result);
66+
else if (call.method.contentEquals("OneSignal#preventDefault"))
67+
this.preventDefault(call, result);
6968
else if (call.method.contentEquals("OneSignal#lifecycleInit"))
7069
this.lifecycleInit();
7170
else
@@ -103,32 +102,25 @@ private void initNotificationOpenedHandlerParams(MethodCall call, Result result)
103102
replySuccess(result, null);
104103
}
105104

106-
107-
private void initNotificationWillShowInForegroundHandlerParams() {
108-
this.hasSetNotificationWillShowInForegroundHandler = true;
109-
}
110-
111-
private void completeNotification(MethodCall call, Result result) {
105+
private void displayNotification(MethodCall call, Result result) {
112106
String notificationId = call.argument("notificationId");
113-
boolean shouldDisplay = call.argument("shouldDisplay");
114-
INotificationReceivedEvent notificationReceivedEvent = notificationReceivedEventCache.get(notificationId);
115-
116-
if (notificationReceivedEvent == null) {
117-
Logging.error("Could not find notification completion block with id: " + notificationId, null);
107+
INotificationWillDisplayEvent event = notificationOnWillDisplayEventCache.get(notificationId);
108+
if (event == null) {
109+
Logging.error("Could not find onWillDisplayNotification event for notification with id: " + notificationId, null);
118110
return;
119111
}
112+
event.notification.display();
113+
replySuccess(result, null);
114+
}
120115

121-
if (shouldDisplay) {
122-
notificationReceivedEvent.complete(notificationReceivedEvent.getNotification());
123-
} else {
124-
notificationReceivedEvent.complete(null);
125-
}
126-
127-
synchronized (notificationReceivedEvent) {
128-
notificationReceivedEventCache.remove(notificationId);
129-
notificationReceivedEvent.notify();
116+
private void preventDefault(MethodCall call, Result result) {
117+
String notificationId = call.argument("notificationId");
118+
INotificationWillDisplayEvent event = notificationOnWillDisplayEventCache.get(notificationId);
119+
if (event == null) {
120+
Logging.error("Could not find onWillDisplayNotification event for notification with id: " + notificationId, null);
121+
return;
130122
}
131-
123+
event.preventDefault();
132124
replySuccess(result, null);
133125
}
134126

@@ -155,31 +147,14 @@ private JSONObject getJsonFromMap(Map<String, Object> map) throws JSONException
155147
}
156148

157149
@Override
158-
public void notificationWillShowInForeground(INotificationReceivedEvent notificationReceivedEvent) {
159-
if (!this.hasSetNotificationWillShowInForegroundHandler) {
160-
notificationReceivedEvent.complete(notificationReceivedEvent.getNotification());
161-
return;
162-
}
163-
150+
public void onWillDisplay(INotificationWillDisplayEvent event) {
164151
INotification notification = notificationReceivedEvent.getNotification();
165-
notificationReceivedEventCache.put(notification.getNotificationId(), notificationReceivedEvent);
166-
152+
notificationLifecycleEventCache.put(notification.getNotificationId(), event);
167153
try {
168-
HashMap<String, Object> receivedMap = OneSignalSerializer.convertNotificationToMap(notification);
169-
invokeMethodOnUiThread("OneSignal#handleNotificationWillShowInForeground", receivedMap);
170-
try {
171-
172-
synchronized (notificationReceivedEvent) {
173-
while(notificationReceivedEventCache.containsKey(notification.getNotificationId()))
174-
notificationReceivedEvent.wait();
175-
}
176-
} catch(InterruptedException e){
177-
Logging.error("InterruptedException" + e.toString(), null);
178-
}
179-
154+
invokeMethodOnUiThread("OneSignal#onWillDisplayNotification", OneSignalSerializer.convertNotificationWillDisplayEventToMap(result));
180155
} catch (JSONException e) {
181156
e.getStackTrace();
182-
Logging.error("Encountered an error attempting to convert INotification object to hash map:" + e.toString(), null);
157+
Logging.error("Encountered an error attempting to convert INotificationWillDisplayEvent object to hash map:" + e.toString(), null);
183158
}
184159
}
185160

@@ -189,9 +164,7 @@ public void onNotificationPermissionChange(boolean permission) {
189164
}
190165

191166
private void lifecycleInit() {
192-
OneSignal.getNotifications().setNotificationWillShowInForegroundHandler(this);
167+
OneSignal.getNotifications().addLifecycleListener(this);
193168
OneSignal.getNotifications().addPermissionChangedHandler(this);
194169
}
195-
196-
197170
}

android/src/main/java/com/onesignal/flutter/OneSignalSerializer.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ static HashMap<String, Object> convertNotificationToMap(INotification notificati
7575
return hash;
7676
}
7777

78+
static HashMap<String, Object> convertNotificationWillDisplayEventToMap(INotificationWillDisplayEvent event) {
79+
HashMap<String, Object> hash = new HashMap<>();
80+
hash.put("notification", convertNotificationToMap(event.getNotification()));
81+
return hash;
82+
}
83+
7884
static HashMap<String, Object> convertNotificationClickResultToMap(INotificationClickResult openResult) throws JSONException {
7985
HashMap<String, Object> hash = new HashMap<>();
8086

example/lib/main.dart

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ class _MyAppState extends State<MyApp>
1616
OneSignalPushSubscriptionObserver,
1717
OneSignalPermissionObserver,
1818
OneSignalInAppMessageLifecycleListener,
19-
OneSignalInAppMessageClickListener {
19+
OneSignalInAppMessageClickListener,
20+
OneSignalNotificationLifecycleListener {
2021
String _debugLabelString = "";
2122
String? _emailAddress;
2223
String? _smsNumber;
@@ -63,19 +64,7 @@ class _MyAppState extends State<MyApp>
6364
});
6465
});
6566

66-
OneSignal.Notifications.setNotificationWillShowInForegroundHandler(
67-
(OSNotificationReceivedEvent event) {
68-
print(
69-
'FOREGROUND HANDLER CALLED WITH: ${event.notification.jsonRepresentation()}');
70-
71-
/// Display Notification, send null to not display
72-
event.complete(null);
73-
74-
this.setState(() {
75-
_debugLabelString =
76-
"Notification received in foreground notification: \n${event.notification.jsonRepresentation().replaceAll("\\n", "\n")}";
77-
});
78-
});
67+
OneSignal.Notifications.addLifecycleListener(this);
7968

8069
OneSignal.InAppMessages.addClickListener(this);
8170

@@ -129,6 +118,24 @@ class _MyAppState extends State<MyApp>
129118
print("ON DID DISMISS IN APP MESSAGE ${event.message.messageId}");
130119
}
131120

121+
void onWillDisplayNotification(OSNotificationWillDisplayEvent event) {
122+
print(
123+
'NOTIFICATION WILL DISPLAY LISTENER CALLED WITH: ${event.notification.jsonRepresentation()}');
124+
125+
/// Display Notification, preventDefault to not display
126+
event.preventDefault();
127+
128+
/// Do async work
129+
130+
/// notification.display() to display after preventing default
131+
event.notification.display();
132+
133+
this.setState(() {
134+
_debugLabelString =
135+
"Notification received in foreground notification: \n${event.notification.jsonRepresentation().replaceAll("\\n", "\n")}";
136+
});
137+
}
138+
132139
void _handleSendTags() {
133140
print("Sending tags");
134141
OneSignal.User.addTagWithKey("test2", "val2");

ios/Classes/OSFlutterCategories.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@
3535
- (NSDictionary *)toJson;
3636
@end
3737

38+
@interface OSNotificationWillDisplayEvent (Flutter)
39+
- (NSDictionary *)toJson;
40+
@end
41+
3842
@interface OSNotificationOpenedResult (Flutter)
3943
- (NSDictionary *)toJson;
4044
@end
@@ -51,4 +55,20 @@
5155
- (FlutterError *)flutterError;
5256
@end
5357

58+
@interface OSInAppMessageWillDismissEvent (Flutter)
59+
- (NSDictionary *)toJson;
60+
@end
61+
62+
@interface OSInAppMessageDidDismissEvent (Flutter)
63+
- (NSDictionary *)toJson;
64+
@end
65+
66+
@interface OSInAppMessageClickEvent (Flutter)
67+
- (NSDictionary *)toJson;
68+
@end
69+
70+
@interface OSInAppMessageClickResult (Flutter)
71+
- (NSDictionary *)toJson;
72+
@end
73+
5474
#endif

ios/Classes/OSFlutterCategories.m

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,16 @@ - (NSDictionary *)toJson {
8484
}
8585
@end
8686

87+
@implementation OSNotificationWillDisplayEvent (Flutter)
88+
- (NSDictionary *)toJson {
89+
NSMutableDictionary *json = [NSMutableDictionary new];
90+
91+
json[@"notification"] = self.notification.toJson;
92+
93+
return json;
94+
}
95+
@end
96+
8797
@implementation OSInAppMessageWillDisplayEvent (Flutter)
8898
- (NSDictionary *)toJson {
8999
NSMutableDictionary *json = [NSMutableDictionary new];

ios/Classes/OSFlutterNotifications.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,11 @@
3030
#import <Flutter/Flutter.h>
3131
#import <OneSignalNotifications/OneSignalNotifications.h>
3232

33-
@interface OSFlutterNotifications : NSObject<FlutterPlugin, OSNotificationPermissionObserver>
33+
@interface OSFlutterNotifications : NSObject<FlutterPlugin, OSNotificationPermissionObserver, OSNotificationLifecycleListener>
3434

3535
@property (strong, nonatomic) FlutterMethodChannel *channel;
3636
+ (instancetype)sharedInstance;
37-
@property (atomic) BOOL hasSetNotificationWillShowInForegroundHandler;
38-
@property (strong, nonatomic) NSMutableDictionary* notificationCompletionCache;
39-
@property (strong, nonatomic) NSMutableDictionary* receivedNotificationCache;
37+
@property (strong, nonatomic) NSMutableDictionary* onWillDisplayEventCache;
4038

4139

4240
@end

ios/Classes/OSFlutterNotifications.m

Lines changed: 22 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,7 @@ + (instancetype)sharedInstance {
3737
static dispatch_once_t onceToken;
3838
dispatch_once(&onceToken, ^{
3939
sharedInstance = [OSFlutterNotifications new];
40-
sharedInstance.hasSetNotificationWillShowInForegroundHandler = false;
41-
sharedInstance.receivedNotificationCache = [NSMutableDictionary new];
42-
sharedInstance.notificationCompletionCache = [NSMutableDictionary new];
40+
sharedInstance.onWillDisplayEventCache = [NSMutableDictionary new];
4341
});
4442
return sharedInstance;
4543
}
@@ -66,10 +64,10 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
6664
[self requestPermission:call withResult:result];
6765
else if ([@"OneSignal#registerForProvisionalAuthorization" isEqualToString:call.method])
6866
[self registerForProvisionalAuthorization:call withResult:result];
69-
else if ([@"OneSignal#initNotificationWillShowInForegroundHandlerParams" isEqualToString:call.method])
70-
[self initNotificationWillShowInForegroundHandlerParams];
71-
else if ([@"OneSignal#completeNotification" isEqualToString:call.method])
72-
[self completeNotification:call withResult:result];
67+
else if ([@"OneSignal#displayNotification" isEqualToString:call.method])
68+
[self displayNotification:call withResult:result];
69+
else if ([@"OneSignal#preventDefault" isEqualToString:call.method])
70+
[self preventDefault:call withResult:result];
7371
else if ([@"OneSignal#initNotificationOpenedHandlerParams" isEqualToString:call.method])
7472
[self initNotificationOpenedHandlerParams:call withResult:result];
7573
else if ([@"OneSignal#lifecycleInit" isEqualToString:call.method])
@@ -103,53 +101,42 @@ - (void)registerForProvisionalAuthorization:(FlutterMethodCall *)call withResult
103101
}
104102

105103
- (void)lifecycleInit:(FlutterMethodCall *)call withResult:(FlutterResult)result {
106-
[OneSignal.Notifications setNotificationWillShowInForegroundHandler:^(OSNotification *notification, OSNotificationDisplayResponse completion) {
107-
[OSFlutterNotifications.sharedInstance handleNotificationWillShowInForeground:notification completion:completion];
108-
}];
109104
[OneSignal.Notifications addPermissionObserver:self];
105+
[OneSignal.Notifications addLifecycleListener:self];
110106
result(nil);
111107
}
112108

113109
- (void)onNotificationPermissionDidChange:(BOOL)permission {
114110
[self.channel invokeMethod:@"OneSignal#onNotificationPermissionDidChange" arguments:@{@"permission" : @(permission)}];
115111
}
116112

117-
#pragma mark Received in Foreground Notification
113+
#pragma mark Received in Notification Lifecycle Event
118114

119-
- (void)initNotificationWillShowInForegroundHandlerParams {
120-
self.hasSetNotificationWillShowInForegroundHandler = YES;
115+
- (void)onWillDisplayNotification:(OSNotificationWillDisplayEvent *)event {
116+
self.onWillDisplayEventCache[event.notification.notificationId] = event;
117+
[self.channel invokeMethod:@"OneSignal#onWillDisplayNotification" arguments:event.toJson];
121118
}
122119

123-
- (void)handleNotificationWillShowInForeground:(OSNotification *)notification completion:(OSNotificationDisplayResponse)completion {
124-
125-
if (!self.hasSetNotificationWillShowInForegroundHandler) {
126-
completion(notification);
120+
- (void)preventDefault:(FlutterMethodCall *)call withResult:(FlutterResult)result {
121+
NSString *notificationId = call.arguments[@"notificationId"];
122+
OSNotificationWillDisplayEvent *event = self.onWillDisplayEventCache[notificationId];
123+
124+
if (!event) {
125+
[OneSignalLog onesignalLog:ONE_S_LL_ERROR message:[NSString stringWithFormat:@"OneSignal (objc): could not find notification will display event for notification with id: %@", notificationId]];
127126
return;
128127
}
129-
self.receivedNotificationCache[notification.notificationId] = notification;
130-
self.notificationCompletionCache[notification.notificationId] = completion;
131-
[self.channel invokeMethod:@"OneSignal#handleNotificationWillShowInForeground" arguments:notification.toJson];
128+
[event preventDefault];
132129
}
133130

134-
- (void)completeNotification:(FlutterMethodCall *)call withResult:(FlutterResult)result {
131+
- (void)displayNotification:(FlutterMethodCall *)call withResult:(FlutterResult)result {
135132
NSString *notificationId = call.arguments[@"notificationId"];
136-
BOOL shouldDisplay = [call.arguments[@"shouldDisplay"] boolValue];
137-
OSNotificationDisplayResponse completion = self.notificationCompletionCache[notificationId];
133+
OSNotificationWillDisplayEvent *event = self.onWillDisplayEventCache[notificationId];
138134

139-
if (!completion) {
140-
[OneSignalLog onesignalLog:ONE_S_LL_ERROR message:[NSString stringWithFormat:@"OneSignal (objc): could not find notification completion block with id: %@", notificationId]];
135+
if (!event) {
136+
[OneSignalLog onesignalLog:ONE_S_LL_ERROR message:[NSString stringWithFormat:@"OneSignal (objc): could not find notification will display event for notification with id: %@", notificationId]];
141137
return;
142138
}
143-
144-
if (shouldDisplay) {
145-
OSNotification *notification = self.receivedNotificationCache[notificationId];
146-
completion(notification);
147-
} else {
148-
completion(nil);
149-
}
150-
151-
[self.notificationCompletionCache removeObjectForKey:notificationId];
152-
[self.receivedNotificationCache removeObjectForKey:notificationId];
139+
[event.notification display];
153140
}
154141

155142
#pragma mark Opened Notification

lib/src/notification.dart

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -375,23 +375,22 @@ class OSAndroidBackgroundImageLayout extends JSONStringRepresentable {
375375
}
376376
}
377377

378-
class OSNotificationReceivedEvent extends JSONStringRepresentable {
378+
extension OSDisplayNotification on OSNotification {
379+
void display() {
380+
OneSignal.Notifications.displayNotification(this.notificationId);
381+
}
382+
}
383+
384+
class OSNotificationWillDisplayEvent extends JSONStringRepresentable {
379385
late OSNotification notification;
380386

381-
OSNotificationReceivedEvent(Map<String, dynamic> json) {
382-
notification = OSNotification(json);
387+
OSNotificationWillDisplayEvent(Map<String, dynamic> json) {
388+
notification = OSNotification(json["notification"].cast<String, dynamic>());
383389
}
384390

385-
void complete(OSNotification? notification) {
391+
void preventDefault() {
386392
if (notification != null) {
387-
OneSignal.Notifications.completeNotification(
388-
notification.notificationId, true);
389-
} else {
390-
print(
391-
'OSNotificationReceivedEvent complete not nill with notification: ' +
392-
this.notification.notificationId);
393-
OneSignal.Notifications.completeNotification(
394-
this.notification.notificationId, false);
393+
OneSignal.Notifications.preventDefault(notification.notificationId);
395394
}
396395
}
397396

0 commit comments

Comments
 (0)