Skip to content

Commit 74e5ea3

Browse files
committed
Fixed issue where both received and open events would fire
* Fixed issue where received event would fire when an action button or attachment notification was received in the background. - The received in the foreground unless the developer specifically sets cogent-available. * Fixed case where application:didReceiveRemoteNotification:fetchCompletionHandler could double fire when content-available was set. * Added addtional duplicate checks to prevent any possible double firing of events.
1 parent 5ad4689 commit 74e5ea3

File tree

4 files changed

+48
-25
lines changed

4 files changed

+48
-25
lines changed

iOS_SDK/OneSignal/OneSignal.m

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -816,13 +816,22 @@ + (void)sendPurchases:(NSArray*)purchases {
816816
// - 2A. iOS 9 - Notification received while app is in focus.
817817
// - 2B. iOS 10 - Notification received/displayed while app is in focus.
818818
+ (void)notificationOpened:(NSDictionary*)messageDict isActive:(BOOL)isActive {
819-
// Should be called first, other methods relay on this global state below.
820-
[OneSignalHelper lastMessageReceived:messageDict];
821-
822819
NSDictionary* customDict = [messageDict objectForKey:@"os_data"];
823820
if (!customDict)
824821
customDict = [messageDict objectForKey:@"custom"];
825822

823+
// Prevent duplicate calls
824+
static NSString* lastMessageID = @"";
825+
if (customDict && customDict[@"i"]) {
826+
NSString* currentNotificationId = customDict[@"i"];
827+
if ([currentNotificationId isEqualToString:lastMessageID])
828+
return;
829+
lastMessageID = customDict[@"i"];
830+
}
831+
832+
// Should be called first, other methods relay on this global state below.
833+
[OneSignalHelper lastMessageReceived:messageDict];
834+
826835
BOOL inAppAlert = false;
827836
if (isActive) {
828837
if (![[NSUserDefaults standardUserDefaults] objectForKey:@"ONESIGNAL_ALERT_OPTION"]) {
@@ -869,7 +878,6 @@ + (void)notificationOpened:(NSDictionary*)messageDict isActive:(BOOL)isActive {
869878
[OneSignal submitNotificationOpened:messageId];
870879
}
871880
else {
872-
873881
//app was in background / not running and opened due to a tap on a notification or an action check what type
874882
NSString* actionSelected = NULL;
875883
OSNotificationActionType type = OSNotificationActionTypeOpened;
@@ -1047,8 +1055,7 @@ + (void) remoteSilentNotification:(UIApplication*)application UserInfo:(NSDictio
10471055
if (userInfo[@"os_data"][@"buttons"] || userInfo[@"at"] || userInfo[@"o"])
10481056
data = userInfo;
10491057

1050-
//If buttons -> Data is buttons
1051-
//Otherwise if titles or body or attachment -> data is everything
1058+
// Genergate local notification for action button and/or attachments.
10521059
if (data) {
10531060
if (NSClassFromString(@"UNUserNotificationCenter")) {
10541061
#if XC8_AVAILABLE
@@ -1060,20 +1067,22 @@ + (void) remoteSilentNotification:(UIApplication*)application UserInfo:(NSDictio
10601067
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
10611068
}
10621069
}
1063-
// Method was called due to a tap on a notification
1070+
// Method was called due to a tap on a notification - Fire open notification
10641071
else if (application.applicationState != UIApplicationStateBackground) {
10651072
[OneSignalHelper lastMessageReceived:userInfo];
1066-
[OneSignalHelper handleNotificationReceived:OSNotificationDisplayTypeNotification];
1073+
if (application.applicationState == UIApplicationStateActive)
1074+
[OneSignalHelper handleNotificationReceived:OSNotificationDisplayTypeNotification];
10671075
[OneSignal notificationOpened:userInfo isActive:NO];
10681076
return;
10691077
}
1070-
1071-
/* Handle the notification reception */
1072-
[OneSignalHelper lastMessageReceived:userInfo];
1073-
if ([OneSignalHelper isRemoteSilentNotification:userInfo])
1074-
[OneSignalHelper handleNotificationReceived:OSNotificationDisplayTypeNone];
1075-
else
1076-
[OneSignalHelper handleNotificationReceived:OSNotificationDisplayTypeNotification];
1078+
// content-available notification received in the background - Fire handleNotificationReceived block in app
1079+
else {
1080+
[OneSignalHelper lastMessageReceived:userInfo];
1081+
if ([OneSignalHelper isRemoteSilentNotification:userInfo])
1082+
[OneSignalHelper handleNotificationReceived:OSNotificationDisplayTypeNone];
1083+
else
1084+
[OneSignalHelper handleNotificationReceived:OSNotificationDisplayTypeNotification];
1085+
}
10771086
}
10781087

10791088
// iOS 8-9 - Entry point when OneSignal action button notifiation is displayed or opened.
@@ -1125,10 +1134,14 @@ + (void)syncHashedEmail:(NSString *)email {
11251134
@end
11261135

11271136
// Swizzles UIApplication class to swizzling the other following classes:
1128-
// - UIApplication - setDelegate: - Used to swizzle all UIApplicationDelegate selectors on the passed in class.
1129-
// - Normally this the AppDelegate class but since UIApplicationDelegate is a "interface" this could be any class.
1130-
// - UNUserNotificationCenter - setDelegate: - For iOS 10 only, swizzle all UNUserNotificationCenterDelegate selectors on the passed in class.
1131-
// - This may or may not be set so we set our own now in registerAsUNNotificationCenterDelegate to an empty class.
1137+
// - UIApplication
1138+
// - setDelegate:
1139+
// - Used to swizzle all UIApplicationDelegate selectors on the passed in class.
1140+
// - Almost always this is the AppDelegate class but since UIApplicationDelegate is an "interface" this could be any class.
1141+
// - UNUserNotificationCenter
1142+
// - setDelegate:
1143+
// - For iOS 10 only, swizzle all UNUserNotificationCenterDelegate selectors on the passed in class.
1144+
// - This may or may not be set so we set our own now in registerAsUNNotificationCenterDelegate to an empty class.
11321145
//
11331146
// Note1: Do NOT move this category to it's own file. This is requried so when the app developer calls OneSignal.initWithLaunchOptions this load+
11341147
// will fire along with it. This is due to how iOS loads .m files into memory instead of classes.

iOS_SDK/OneSignal/OneSignalHelper.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,10 @@
5757
#endif
5858

5959
// - Notifications
60-
+ (BOOL) isCapableOfGettingNotificationTypes;
60+
+ (BOOL)isCapableOfGettingNotificationTypes;
6161
+ (UILocalNotification*)prepareUILocalNotification:(NSDictionary*)data :(NSDictionary*)userInfo;
6262
+ (BOOL)verifyURL:(NSString *)urlString;
63-
+ (BOOL) isRemoteSilentNotification:(NSDictionary*)msg;
63+
+ (BOOL)isRemoteSilentNotification:(NSDictionary*)msg;
6464

6565
// - Networking
6666
+ (NSNumber*)getNetType;

iOS_SDK/OneSignal/OneSignalHelper.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ + (void)handleNotificationReceived:(OSNotificationDisplayType)displayType {
456456
OSNotificationPayload *payload = [[OSNotificationPayload alloc] initWithRawMessage:lastMessageReceived];
457457
OSNotification *notification = [[OSNotification alloc] initWithPayload:payload displayType:displayType];
458458

459-
//Prevent duplicate calls to same action
459+
// Prevent duplicate calls to same receive event
460460
static NSString* lastMessageID = @"";
461461
if ([payload.notificationID isEqualToString:lastMessageID])
462462
return;
@@ -474,7 +474,7 @@ + (void)handleNotificationAction:(OSNotificationActionType)actionType actionID:(
474474
OSNotification *notification = [[OSNotification alloc] initWithPayload:payload displayType:displayType];
475475
OSNotificationOpenedResult * result = [[OSNotificationOpenedResult alloc] initWithNotification:notification action:action];
476476

477-
//Prevent duplicate calls to same action
477+
// Prevent duplicate calls to same action
478478
static NSString* lastMessageID = @"";
479479
if ([payload.notificationID isEqualToString:lastMessageID])
480480
return;

iOS_SDK/OneSignal/UNUserNotificationCenter+OneSignal.m

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#import "OneSignal.h"
3333
#import "OneSignalHelper.h"
3434
#import "OneSignalSelectorHelpers.h"
35+
#import "UIApplicationDelegate+OneSignal.h"
3536

3637

3738
#if XC8_AVAILABLE
@@ -117,6 +118,7 @@ - (void)onesignalUserNotificationCenter:(UNUserNotificationCenter *)center
117118
isTextReply:false
118119
actionIdentifier:nil
119120
userText:nil
121+
fromPresentNotification:true
120122
withCompletionHandler:^() {}];
121123
}
122124

@@ -147,6 +149,7 @@ - (void)onesignalUserNotificationCenter:(UNUserNotificationCenter *)center
147149
isTextReply:isTextReply
148150
actionIdentifier:response.actionIdentifier
149151
userText:userText
152+
fromPresentNotification:false
150153
withCompletionHandler:completionHandler];
151154
}
152155
else
@@ -187,6 +190,7 @@ + (void)callLegacyAppDeletegateSelector:(UNNotification *)notification
187190
isTextReply:(BOOL)isTextReply
188191
actionIdentifier:(NSString*)actionIdentifier
189192
userText:(NSString*)userText
193+
fromPresentNotification:(BOOL)fromPresentNotification
190194
withCompletionHandler:(void(^)())completionHandler {
191195
[OneSignal onesignal_Log:ONE_S_LL_VERBOSE message:@"callLegacyAppDeletegateSelector:withCompletionHandler: Fired!"];
192196

@@ -252,8 +256,12 @@ + (void)callLegacyAppDeletegateSelector:(UNNotification *)notification
252256
[sharedApp.delegate application:sharedApp handleActionWithIdentifier:actionIdentifier forRemoteNotification:remoteUserInfo completionHandler:^() {
253257
completionHandler();
254258
}];
255-
else if ([sharedApp.delegate respondsToSelector:@selector(application:didReceiveRemoteNotification:fetchCompletionHandler:)]) {
256-
// NOTE: Should always be true as our AppDelegate swizzling should be there unless something else unswizzled it.
259+
// Always trigger selector for open events and for non-content-available receive events.
260+
// content-available seema to be an odd expection to iOS 10's fallback rules for legacy selectors.
261+
else if ([sharedApp.delegate respondsToSelector:@selector(application:didReceiveRemoteNotification:fetchCompletionHandler:)] &&
262+
(!fromPresentNotification ||
263+
![[notification.request.trigger valueForKey:@"_isContentAvailable"] boolValue])) {
264+
// NOTE: Should always be true as our AppDelegate swizzling should be there unless something else unswizzled it.
257265
[sharedApp.delegate application:sharedApp didReceiveRemoteNotification:remoteUserInfo fetchCompletionHandler:^(UIBackgroundFetchResult result) {
258266
// Call iOS 10's compleationHandler from iOS 9's completion handler.
259267
completionHandler();
@@ -262,6 +270,8 @@ + (void)callLegacyAppDeletegateSelector:(UNNotification *)notification
262270
else
263271
completionHandler();
264272
}
273+
else
274+
completionHandler();
265275
}
266276

267277
@end

0 commit comments

Comments
 (0)