Skip to content

Commit f0d5253

Browse files
committed
Fixed AppDelegate compatibility, isAppInFocus, and stability fix
* Fix for application:didReceiveRemoteNotification:fetchCompletionHandler: no longer firing on the AppDelegate. - Now calls this from UNUserNotificationCenterDelegate's userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler * Added isAppInFocus property to OSNotification to match Android's properties. * Fixed crash when opening a notification from a cold start if OneSignal.initWithLaunchOptions was called with a delay.
1 parent 78954a4 commit f0d5253

File tree

4 files changed

+46
-23
lines changed

4 files changed

+46
-23
lines changed

iOS_SDK/OneSignal/OneSignal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,9 @@ typedef OSNotificationDisplayType OSInFocusDisplayOption;
148148
Set to false when app is in focus and in-app alerts are disabled, or the remote notification is silent. */
149149
@property(readonly, getter=wasShown)BOOL shown;
150150

151+
/* Set to true if the app was in focus when the notification */
152+
@property(readonly, getter=wasAppInFocus)BOOL isAppInFocus;
153+
151154
/* Set to true when the received notification is silent
152155
Silent means there is no alert, sound, or badge payload in the aps dictionary
153156
requires remote-notification within UIBackgroundModes array of the Info.plist */

iOS_SDK/OneSignal/OneSignal.m

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,22 +1206,21 @@ - (void)oneSignalReceivedRemoteNotification:(UIApplication*)application userInfo
12061206
// User Tap on Notification while app was in background - OR - Notification received (silent or not, foreground or background) on iOS 7+
12071207
- (void) oneSignalRemoteSilentNotification:(UIApplication*)application UserInfo:(NSDictionary*)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult)) completionHandler {
12081208

1209-
if([OneSignal app_id]) {
1210-
1211-
//Call notificationAction if app is active -> not a silent notification but rather user tap on notification
1212-
//Unless iOS 10+ then call remoteSilentNotification instead.
1213-
if([UIApplication sharedApplication].applicationState == UIApplicationStateActive && userInfo[@"aps"][@"alert"])
1209+
if ([OneSignal app_id]) {
1210+
// Call notificationAction if app is active -> not a silent notification but rather user tap on notification
1211+
// Unless iOS 10+ then call remoteSilentNotification instead.
1212+
if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive && userInfo[@"aps"][@"alert"])
12141213
[OneSignal notificationOpened:userInfo isActive:YES];
1215-
else [OneSignal remoteSilentNotification:application UserInfo:userInfo];
1216-
1214+
else
1215+
[OneSignal remoteSilentNotification:application UserInfo:userInfo];
12171216
}
12181217

12191218
if ([self respondsToSelector:@selector(oneSignalRemoteSilentNotification:UserInfo:fetchCompletionHandler:)]) {
12201219
[self oneSignalRemoteSilentNotification:application UserInfo:userInfo fetchCompletionHandler:completionHandler];
12211220
return;
12221221
}
12231222

1224-
//Make sure not a cold start from tap on notification (OS doesn't call didReceiveRemoteNotification)
1223+
// Make sure not a cold start from tap on notification (OS doesn't call didReceiveRemoteNotification)
12251224
if ([self respondsToSelector:@selector(oneSignalReceivedRemoteNotification:userInfo:)] && ![[OneSignal valueForKey:@"coldStartFromTapOnNotification"] boolValue])
12261225
[self oneSignalReceivedRemoteNotification:application userInfo:userInfo];
12271226

iOS_SDK/OneSignal/OneSignalHelper.m

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ - (id)initWithRawMessage:(NSDictionary*)message {
144144
@end
145145

146146
@implementation OSNotification
147-
@synthesize payload = _payload, shown = _shown, silentNotification = _silentNotification, displayType = _displayType;
147+
@synthesize payload = _payload, shown = _shown, isAppInFocus = _isAppInFocus, silentNotification = _silentNotification, displayType = _displayType;
148148

149149
#if XC8_AVAILABLE
150150
@synthesize mutableContent = _mutableContent;
@@ -165,11 +165,12 @@ - (id)initWithPayload:(OSNotificationPayload *)payload displayType:(OSNotificati
165165

166166
_shown = true;
167167

168-
BOOL isActive = [[UIApplication sharedApplication] applicationState] == UIApplicationStateActive;
168+
_isAppInFocus = [[UIApplication sharedApplication] applicationState] == UIApplicationStateActive;
169169

170170
//If remote silent -> shown = false
171171
//If app is active and in-app alerts are not enabled -> shown = false
172-
if(_silentNotification || (isActive && [[NSUserDefaults standardUserDefaults] boolForKey:@"ONESIGNAL_ALERT_OPTION"] == OSNotificationDisplayTypeNone))
172+
if (_silentNotification ||
173+
(_isAppInFocus && [[NSUserDefaults standardUserDefaults] boolForKey:@"ONESIGNAL_ALERT_OPTION"] == OSNotificationDisplayTypeNone))
173174
_shown = false;
174175

175176
}
@@ -216,10 +217,11 @@ - (NSString*)stringify {
216217
if(self.displayType)
217218
[obj setObject:@(self.displayType) forKeyedSubscript: @"displayType"];
218219

219-
if(self.shown)
220-
[obj setObject:@(self.shown) forKeyedSubscript: @"shown"];
221220

222-
if(self.silentNotification)
221+
[obj setObject:@(self.shown) forKeyedSubscript: @"shown"];
222+
[obj setObject:@(self.isAppInFocus) forKeyedSubscript: @"isAppInFocus"];
223+
224+
if (self.silentNotification)
223225
[obj setObject:@(self.silentNotification) forKeyedSubscript: @"silentNotification"];
224226

225227

@@ -494,7 +496,7 @@ + (id)prepareUNNotificationRequest:(NSDictionary *)data :(NSDictionary *)userInf
494496
if(!NSClassFromString(@"UNNotificationAction") || !NSClassFromString(@"UNNotificationRequest")) return NULL;
495497

496498
NSMutableArray * actionArray = [[NSMutableArray alloc] init];
497-
for( NSDictionary* button in data[@"o"]) {
499+
for(NSDictionary* button in data[@"o"]) {
498500
NSString* title = button[@"n"] != NULL ? button[@"n"] : @"";
499501
NSString* buttonID = button[@"i"] != NULL ? button[@"i"] : title;
500502
id action = [NSClassFromString(@"UNNotificationAction") actionWithIdentifier:buttonID title:title options:UNNotificationActionOptionForeground];
@@ -667,7 +669,6 @@ + (void)enqueueRequest:(NSURLRequest*)request onSuccess:(OSResultSuccessBlock)su
667669
}
668670

669671
+ (void)enqueueRequest:(NSURLRequest*)request onSuccess:(OSResultSuccessBlock)successBlock onFailure:(OSFailureBlock)failureBlock isSynchronous:(BOOL)isSynchronous {
670-
671672
[OneSignal onesignal_Log:ONE_S_LL_VERBOSE message: [NSString stringWithFormat:@"request.body: %@", [[NSString alloc]initWithData:request.HTTPBody encoding:NSUTF8StringEncoding]]];
672673

673674
if (isSynchronous) {

iOS_SDK/OneSignal/UNUserNotificationCenter+OneSignal.m

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ @interface OneSignal (UN_extra)
4545
+ (void)notificationOpened:(NSDictionary*)messageDict isActive:(BOOL)isActive;
4646
@end
4747

48+
// This class hooks into the following iSO 10 UNUserNotificationCenterDelegate selectors:
49+
// - userNotificationCenter:willPresentNotification:withCompletionHandler:
50+
// - Reads kOSSettingsKeyInFocusDisplayOption to respect it's setting.
51+
// - userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:
52+
// - Used to process opening a notifications.
53+
// - The presents of this selector tells iOS to no longer fire `application:didReceiveRemoteNotification:fetchCompletionHandler:`.
54+
// We call this to maintain existing behavior.
4855

4956
@implementation sizzleUNUserNotif
5057

@@ -119,7 +126,7 @@ - (void)onesignalUserNotificationCenter:(id)center didReceiveNotificationRespons
119126

120127
NSDictionary* usrInfo = [[[[response performSelector:@selector(notification)] valueForKey:@"request"] valueForKey:@"content"] valueForKey:@"userInfo"];
121128
if (!usrInfo || [usrInfo count] == 0) {
122-
[sizzleUNUserNotif tunnelToDelegate:center :response :completionHandler];
129+
[sizzleUNUserNotif tunnelToDelegate:center response:response handler:completionHandler];
123130
return;
124131
}
125132

@@ -150,7 +157,7 @@ - (void)onesignalUserNotificationCenter:(id)center didReceiveNotificationRespons
150157
BOOL isActive = [UIApplication sharedApplication].applicationState == UIApplicationStateActive &&
151158
[[[NSUserDefaults standardUserDefaults] objectForKey:@"ONESIGNAL_ALERT_OPTION"] intValue] != OSNotificationDisplayTypeNotification;
152159
[OneSignal notificationOpened:usrInfo isActive:isActive];
153-
[sizzleUNUserNotif tunnelToDelegate:center :response :completionHandler];
160+
[sizzleUNUserNotif tunnelToDelegate:center response:response handler:completionHandler];
154161
return;
155162
}
156163

@@ -179,18 +186,31 @@ - (void)onesignalUserNotificationCenter:(id)center didReceiveNotificationRespons
179186
userInfo[@"aps"] = @{ @"alert" : userInfo[@"m"] };
180187
}
181188

182-
BOOL isActive = [UIApplication sharedApplication].applicationState == UIApplicationStateActive &&
183-
[[[NSUserDefaults standardUserDefaults] objectForKey:@"ONESIGNAL_ALERT_OPTION"] intValue] != OSNotificationDisplayTypeNotification;
189+
UIApplication *sharedApp = [UIApplication sharedApplication];
184190

191+
BOOL isActive = sharedApp.applicationState == UIApplicationStateActive &&
192+
[[[NSUserDefaults standardUserDefaults] objectForKey:@"ONESIGNAL_ALERT_OPTION"] intValue] != OSNotificationDisplayTypeNotification;
185193

186-
[OneSignal notificationOpened:userInfo isActive:isActive];
187-
[sizzleUNUserNotif tunnelToDelegate:center :response :completionHandler];
194+
if ([OneSignal app_id])
195+
[OneSignal notificationOpened:userInfo isActive:isActive];
196+
[sizzleUNUserNotif tunnelToDelegate:center response:response handler:completionHandler];
188197

198+
// Call orginal selector if one was set.
189199
if ([self respondsToSelector:@selector(onesignalUserNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:)])
190200
[self onesignalUserNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:completionHandler];
201+
else if ([sharedApp.delegate respondsToSelector:@selector(application:didReceiveRemoteNotification:fetchCompletionHandler:)]) {
202+
// Call depercated pre-iOS 10 selector if one as set on the AppDelegate.
203+
// NOTE: Should always be true as our AppDelegate swizzling should be there unless something else unsizzled it.
204+
[sharedApp.delegate application:sharedApp didReceiveRemoteNotification:usrInfo fetchCompletionHandler:^(UIBackgroundFetchResult result) {
205+
// Call iOS 10's compleationHandler from iOS 9's completion handler.
206+
completionHandler();
207+
}];
208+
}
191209
}
192210

193-
+ (void)tunnelToDelegate:(id)center :(id)response :(void (^)())handler {
211+
// Depercated - [OneSignal notificationCenterDelegate] - Now handled by swizzling.
212+
// Just need to keep the `handler();` call
213+
+ (void)tunnelToDelegate:(id)center response:(id)response handler:(void (^)())handler {
194214

195215
if ([[OneSignal notificationCenterDelegate] respondsToSelector:@selector(userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:)])
196216
[[OneSignal notificationCenterDelegate] userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:handler];

0 commit comments

Comments
 (0)