Skip to content

Commit 381c5ac

Browse files
committed
Calling all 6 Legacy notifiation selectors for compatability
1 parent 67a7013 commit 381c5ac

File tree

3 files changed

+113
-47
lines changed

3 files changed

+113
-47
lines changed

iOS_SDK/OneSignal/OneSignal.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1303,7 +1303,7 @@ + (void)load {
13031303
return;
13041304

13051305
injectToProperClass(@selector(setOneSignalUNDelegate:),
1306-
@selector(setDelegate:), @[], [sizzleUNUserNotif class], UNUserNotificationCenterClass);
1306+
@selector(setDelegate:), @[], [swizzleUNUserNotif class], UNUserNotificationCenterClass);
13071307

13081308
[OneSignalHelper registerAsUNNotificationCenterDelegate];
13091309
#endif

iOS_SDK/OneSignal/UNUserNotificationCenter+OneSignal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
#import "OneSignal.h"
3232

3333
#if XC8_AVAILABLE
34-
@interface sizzleUNUserNotif : NSObject
34+
@interface swizzleUNUserNotif : NSObject
3535
@end
3636
#endif
3737

iOS_SDK/OneSignal/UNUserNotificationCenter+OneSignal.m

Lines changed: 111 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ + (void)notificationOpened:(NSDictionary*)messageDict isActive:(BOOL)isActive;
5353
// - The presents of this selector tells iOS to no longer fire `application:didReceiveRemoteNotification:fetchCompletionHandler:`.
5454
// We call this to maintain existing behavior.
5555

56-
@implementation sizzleUNUserNotif
56+
@implementation swizzleUNUserNotif
5757

5858
static Class delegateUNClass = nil;
5959

@@ -65,21 +65,21 @@ @implementation sizzleUNUserNotif
6565
// - Selector will be called once if developer does not set a UNUserNotificationCenter delegate.
6666
// - Selector will be called a 2nd time if the developer does set one.
6767
- (void) setOneSignalUNDelegate:(id)delegate {
68-
[OneSignal onesignal_Log:ONE_S_LL_VERBOSE message:@"sizzleUNUserNotif setOneSignalUNDelegate Fired!"];
68+
[OneSignal onesignal_Log:ONE_S_LL_VERBOSE message:@"swizzleUNUserNotif setOneSignalUNDelegate Fired!"];
6969

7070
delegateUNClass = getClassWithProtocolInHierarchy([delegate class], @protocol(UNUserNotificationCenterDelegate));
7171
delegateUNSubclasses = ClassGetSubclasses(delegateUNClass);
7272

7373
injectToProperClass(@selector(onesignalUserNotificationCenter:willPresentNotification:withCompletionHandler:),
74-
@selector(userNotificationCenter:willPresentNotification:withCompletionHandler:), delegateUNSubclasses, [sizzleUNUserNotif class], delegateUNClass);
74+
@selector(userNotificationCenter:willPresentNotification:withCompletionHandler:), delegateUNSubclasses, [swizzleUNUserNotif class], delegateUNClass);
7575

7676
injectToProperClass(@selector(onesignalUserNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:),
77-
@selector(userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:), delegateUNSubclasses, [sizzleUNUserNotif class], delegateUNClass);
77+
@selector(userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:), delegateUNSubclasses, [swizzleUNUserNotif class], delegateUNClass);
7878

7979
[self setOneSignalUNDelegate:delegate];
8080
}
8181

82-
// Apples docs - Called when a notification is delivered to a foreground app.
82+
// Apple's docs - Called when a notification is delivered to a foreground app.
8383
- (void)onesignalUserNotificationCenter:(UNUserNotificationCenter *)center
8484
willPresentNotification:(UNNotification *)notification
8585
withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
@@ -121,30 +121,30 @@ - (void)onesignalUserNotificationCenter:(UNUserNotificationCenter *)center
121121
}
122122

123123
// Apple's docs - Called to let your app know which action was selected by the user for a given notification.
124-
- (void)onesignalUserNotificationCenter:(id)center didReceiveNotificationResponse:(id)response withCompletionHandler:(void(^)())completionHandler {
124+
- (void)onesignalUserNotificationCenter:(UNUserNotificationCenter *)center
125+
didReceiveNotificationResponse:(UNNotificationResponse *)response
126+
withCompletionHandler:(void(^)())completionHandler {
125127
[OneSignal onesignal_Log:ONE_S_LL_VERBOSE message:@"onesignalUserNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: Fired!"];
126128

127-
NSDictionary* usrInfo = [[[[response performSelector:@selector(notification)] valueForKey:@"request"] valueForKey:@"content"] valueForKey:@"userInfo"];
128-
if (!usrInfo || [usrInfo count] == 0) {
129-
[sizzleUNUserNotif tunnelToDelegate:center response:response handler:completionHandler];
130-
return;
131-
}
129+
BOOL isActive = [UIApplication sharedApplication].applicationState == UIApplicationStateActive &&
130+
[[[NSUserDefaults standardUserDefaults] objectForKey:@"ONESIGNAL_ALERT_OPTION"] intValue] != OSNotificationDisplayTypeNotification;
132131

132+
NSDictionary* remoteUserInfo = response.notification.request.content.userInfo;
133133
NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init],
134134
*customDict = [[NSMutableDictionary alloc] init],
135135
*additionalData = [[NSMutableDictionary alloc] init];
136136
NSMutableArray *optionsDict = [[NSMutableArray alloc] init];
137137

138-
NSMutableDictionary* buttonsDict = usrInfo[@"os_data"][@"buttons"];
139-
NSMutableDictionary* custom = usrInfo[@"custom"];
138+
NSMutableDictionary* buttonsDict = remoteUserInfo[@"os_data"][@"buttons"];
139+
NSMutableDictionary* custom = remoteUserInfo[@"custom"];
140140
if (buttonsDict) {
141-
[userInfo addEntriesFromDictionary:usrInfo];
141+
[userInfo addEntriesFromDictionary:remoteUserInfo];
142142
NSArray* o = buttonsDict[@"o"];
143143
if (o)
144144
[optionsDict addObjectsFromArray:o];
145145
}
146146
else if (custom) {
147-
[userInfo addEntriesFromDictionary:usrInfo];
147+
[userInfo addEntriesFromDictionary:remoteUserInfo];
148148
[customDict addEntriesFromDictionary:custom];
149149
NSDictionary *a = customDict[@"a"];
150150
NSArray *o = userInfo[@"o"];
@@ -153,13 +153,6 @@ - (void)onesignalUserNotificationCenter:(id)center didReceiveNotificationRespons
153153
if (o)
154154
[optionsDict addObjectsFromArray:o];
155155
}
156-
else {
157-
BOOL isActive = [UIApplication sharedApplication].applicationState == UIApplicationStateActive &&
158-
[[[NSUserDefaults standardUserDefaults] objectForKey:@"ONESIGNAL_ALERT_OPTION"] intValue] != OSNotificationDisplayTypeNotification;
159-
[OneSignal notificationOpened:usrInfo isActive:isActive];
160-
[sizzleUNUserNotif tunnelToDelegate:center response:response handler:completionHandler];
161-
return;
162-
}
163156

164157
NSMutableArray* buttonArray = [[NSMutableArray alloc] init];
165158
for (NSDictionary* button in optionsDict) {
@@ -172,7 +165,7 @@ - (void)onesignalUserNotificationCenter:(id)center didReceiveNotificationRespons
172165
additionalData[@"actionSelected"] = [response valueForKey:@"actionIdentifier"];
173166
additionalData[@"actionButtons"] = buttonArray;
174167

175-
NSDictionary* os_data = usrInfo[@"os_data"];
168+
NSDictionary* os_data = remoteUserInfo[@"os_data"];
176169
if (os_data) {
177170
[userInfo addEntriesFromDictionary:os_data];
178171
if (userInfo[@"os_data"][@"buttons"][@"m"])
@@ -182,40 +175,113 @@ - (void)onesignalUserNotificationCenter:(id)center didReceiveNotificationRespons
182175
else {
183176
customDict[@"a"] = additionalData;
184177
userInfo[@"custom"] = customDict;
185-
if(userInfo[@"m"])
186-
userInfo[@"aps"] = @{ @"alert" : userInfo[@"m"] };
178+
if (userInfo[@"m"])
179+
userInfo[@"aps"] = @{ @"alert": userInfo[@"m"] };
187180
}
188181

189-
UIApplication *sharedApp = [UIApplication sharedApplication];
190-
191-
BOOL isActive = sharedApp.applicationState == UIApplicationStateActive &&
192-
[[[NSUserDefaults standardUserDefaults] objectForKey:@"ONESIGNAL_ALERT_OPTION"] intValue] != OSNotificationDisplayTypeNotification;
193-
194182
if ([OneSignal app_id])
195183
[OneSignal notificationOpened:userInfo isActive:isActive];
196-
[sizzleUNUserNotif tunnelToDelegate:center response:response handler:completionHandler];
184+
185+
// For depercated OSUserNotificationCenterDelegate
186+
[swizzleUNUserNotif tunnelToDelegate:center response:response handler:completionHandler];
197187

198188
// Call orginal selector if one was set.
199189
if ([self respondsToSelector:@selector(onesignalUserNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:)])
200190
[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-
}
191+
else
192+
[swizzleUNUserNotif callLegacyAppDeletegateSelector:response withCompletionHandler:completionHandler];
209193
}
210194

211195
// 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 {
214-
215-
if ([[OneSignal notificationCenterDelegate] respondsToSelector:@selector(userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:)])
196+
+ (BOOL)tunnelToDelegate:(id)center response:(id)response handler:(void (^)())handler {
197+
if ([[OneSignal notificationCenterDelegate] respondsToSelector:@selector(userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:)]) {
216198
[[OneSignal notificationCenterDelegate] userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:handler];
217-
else
218-
handler();
199+
return true;
200+
}
201+
202+
return false;
203+
}
204+
205+
// Calls depercated pre-iOS 10 selector if one is set on the AppDelegate.
206+
// - application:didReceiveLocalNotification:
207+
// - application:didReceiveRemoteNotification:fetchCompletionHandler:
208+
// - application:handleActionWithIdentifier:forLocalNotification:withResponseInfo:completionHandler:
209+
// - application:handleActionWithIdentifier:forRemoteNotification:withResponseInfo:completionHandler:
210+
// - application:handleActionWithIdentifier:forLocalNotification:completionHandler:
211+
// - application:handleActionWithIdentifier:forRemoteNotification:completionHandler:
212+
+ (void)callLegacyAppDeletegateSelector:(UNNotificationResponse *)response
213+
withCompletionHandler:(void(^)())completionHandler {
214+
UIApplication *sharedApp = [UIApplication sharedApplication];
215+
216+
BOOL isTextReply = [response isKindOfClass:NSClassFromString(@"UNTextInputNotificationResponse")];
217+
BOOL isLegacyLocalNotif = [response.notification.request.trigger isKindOfClass:NSClassFromString(@"UNLegacyNotificationTrigger")];
218+
BOOL isCustomAction = ![@"com.apple.UNNotificationDefaultActionIdentifier" isEqualToString:response.actionIdentifier];
219+
// BOOL isRemote = [response.notification.request.trigger isKindOfClass:NSClassFromString(@"UNPushNotificationTrigger")];
220+
221+
if (isLegacyLocalNotif) {
222+
UILocalNotification *localNotif = [NSClassFromString(@"UIConcreteLocalNotification") alloc];
223+
localNotif.alertBody = response.notification.request.content.body;
224+
localNotif.alertTitle = response.notification.request.content.title;
225+
localNotif.applicationIconBadgeNumber = [response.notification.request.content.badge integerValue];
226+
NSString* soundName = [response.notification.request.content.sound valueForKey:@"_toneFileName"];
227+
if (!soundName)
228+
soundName = @"UILocalNotificationDefaultSoundName";
229+
localNotif.soundName = soundName;
230+
localNotif.alertLaunchImage = response.notification.request.content.launchImageName;
231+
localNotif.userInfo = response.notification.request.content.userInfo;
232+
localNotif.category = response.notification.request.content.categoryIdentifier;
233+
localNotif.hasAction = true; // Defaults to true, UNLocalNotification doesn't seem to have a flag for this.
234+
localNotif.fireDate = response.notification.date;
235+
localNotif.timeZone = [response.notification.request.trigger valueForKey:@"_timeZone"];
236+
localNotif.repeatInterval = [response.notification.request.trigger valueForKey:@"_repeatInterval"];
237+
localNotif.repeatCalendar = [response.notification.request.trigger valueForKey:@"_repeatCalendar"];
238+
// localNotif.region =
239+
// localNotif.regionTriggersOnce =
240+
241+
if (isTextReply &&
242+
[sharedApp.delegate respondsToSelector:@selector(application:handleActionWithIdentifier:forLocalNotification:withResponseInfo:completionHandler:)]) {
243+
NSDictionary* dict = @{UIUserNotificationActionResponseTypedTextKey: [response valueForKey:@"userText"]};
244+
[sharedApp.delegate application:sharedApp handleActionWithIdentifier:response.actionIdentifier forLocalNotification:localNotif withResponseInfo:dict completionHandler:^() {
245+
completionHandler();
246+
}];
247+
}
248+
else if (isCustomAction &&
249+
[sharedApp.delegate respondsToSelector:@selector(application:handleActionWithIdentifier:forLocalNotification:completionHandler:)])
250+
[sharedApp.delegate application:sharedApp handleActionWithIdentifier:response.actionIdentifier forLocalNotification:localNotif completionHandler:^() {
251+
completionHandler();
252+
}];
253+
else if ([sharedApp.delegate respondsToSelector:@selector(application:didReceiveLocalNotification:)]) {
254+
[sharedApp.delegate application:sharedApp didReceiveLocalNotification:localNotif];
255+
completionHandler();
256+
}
257+
else
258+
completionHandler();
259+
}
260+
else {
261+
NSDictionary* remoteUserInfo = response.notification.request.content.userInfo;
262+
263+
if (isTextReply &&
264+
[sharedApp.delegate respondsToSelector:@selector(application:handleActionWithIdentifier:forRemoteNotification:withResponseInfo:completionHandler:)]) {
265+
NSDictionary* responseInfo = @{UIUserNotificationActionResponseTypedTextKey: [response valueForKey:@"userText"]};
266+
[sharedApp.delegate application:sharedApp handleActionWithIdentifier:response.actionIdentifier forRemoteNotification:remoteUserInfo withResponseInfo:responseInfo completionHandler:^() {
267+
completionHandler();
268+
}];
269+
}
270+
else if (isCustomAction &&
271+
[sharedApp.delegate respondsToSelector:@selector(application:handleActionWithIdentifier:forRemoteNotification:completionHandler:)])
272+
[sharedApp.delegate application:sharedApp handleActionWithIdentifier:response.actionIdentifier forRemoteNotification:remoteUserInfo completionHandler:^() {
273+
completionHandler();
274+
}];
275+
else if ([sharedApp.delegate respondsToSelector:@selector(application:didReceiveRemoteNotification:fetchCompletionHandler:)]) {
276+
// NOTE: Should always be true as our AppDelegate swizzling should be there unless something else unswizzled it.
277+
[sharedApp.delegate application:sharedApp didReceiveRemoteNotification:remoteUserInfo fetchCompletionHandler:^(UIBackgroundFetchResult result) {
278+
// Call iOS 10's compleationHandler from iOS 9's completion handler.
279+
completionHandler();
280+
}];
281+
}
282+
else
283+
completionHandler();
284+
}
219285
}
220286

221287
@end

0 commit comments

Comments
 (0)