Skip to content

Commit b268b9b

Browse files
committed
feat: enhance manual integration support and swizzling control
- Added APIs for manual notification handling and lifecycle observation when swizzling is disabled. - Introduced a new constant for controlling swizzling via Info.plist.
1 parent 3092003 commit b268b9b

5 files changed

Lines changed: 61 additions & 39 deletions

File tree

iOS_SDK/OneSignalSDK/OneSignalCore/Source/OneSignalCommonDefines.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@
155155
#define GDPR_CONSENT_GRANTED @"GDPR_CONSENT_GRANTED"
156156
#define ONESIGNAL_REQUIRE_PRIVACY_CONSENT @"OneSignal_require_privacy_consent"
157157

158+
// Swizzling
159+
#define ONESIGNAL_DISABLE_SWIZZLING @"OneSignal_disable_swizzling"
160+
158161
// Badge handling
159162
#define ONESIGNAL_DISABLE_BADGE_CLEARING @"OneSignal_disable_badge_clearing"
160163
#define ONESIGNAL_APP_GROUP_NAME_KEY @"OneSignal_app_groups_key"

iOS_SDK/OneSignalSDK/OneSignalNotifications/Categories/UNUserNotificationCenter+OneSignalNotifications.m

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -377,19 +377,7 @@ + (BOOL)isDismissEvent:(UNNotificationResponse *)response {
377377
}
378378

379379
+ (void)processiOS10Open:(UNNotificationResponse*)response {
380-
if (![OneSignalConfigManager getAppId])
381-
return;
382-
383-
if ([OneSignalNotificationsUNUserNotificationCenter isDismissEvent:response])
384-
return;
385-
386-
if (![OneSignalCoreHelper isOneSignalPayload:response.notification.request.content.userInfo])
387-
return;
388-
389-
let userInfo = [OneSignalCoreHelper formatApsPayloadIntoStandard:response.notification.request.content.userInfo
390-
identifier:response.actionIdentifier];
391-
392-
[OSNotificationsManager notificationReceived:userInfo wasOpened:YES];
380+
[OSNotificationsManager handleNotificationResponse:response];
393381
}
394382

395383
// Calls depercated pre-iOS 10 selector if one is set on the AppDelegate.

iOS_SDK/OneSignalSDK/OneSignalNotifications/OSNotificationsManager.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ NS_SWIFT_NAME(onClick(event:));
6565
+ (void)addPermissionObserver:(NSObject<OSNotificationPermissionObserver>*_Nonnull)observer NS_REFINED_FOR_SWIFT;
6666
+ (void)removePermissionObserver:(NSObject<OSNotificationPermissionObserver>*_Nonnull)observer NS_REFINED_FOR_SWIFT;
6767
+ (void)clearAll;
68+
// Manual integration APIs (for use when swizzling is disabled via Info.plist)
69+
+ (void)didRegisterForRemoteNotifications:(UIApplication *_Nonnull)app deviceToken:(NSData *_Nonnull)inDeviceToken;
70+
+ (void)handleDidFailRegisterForRemoteNotification:(NSError *_Nonnull)err;
71+
+ (BOOL)receiveRemoteNotification:(UIApplication *_Nonnull)application UserInfo:(NSDictionary *_Nonnull)userInfo completionHandler:(void (^_Nonnull)(UIBackgroundFetchResult))completionHandler;
72+
+ (void)handleWillPresentNotificationInForegroundWithPayload:(NSDictionary *_Nonnull)payload withCompletion:(OSNotificationDisplayResponse _Nonnull)completion;
73+
+ (void)handleNotificationResponse:(UNNotificationResponse *_Nonnull)response;
74+
+ (void)setBadgeCount:(NSInteger)badgeCount;
6875
@end
6976

7077

@@ -116,10 +123,8 @@ NS_SWIFT_NAME(onClick(event:));
116123
+ (void)handleNotificationActionWithUrl:(NSString* _Nullable)url actionID:(NSString* _Nonnull)actionID;
117124
+ (void)clearBadgeCount:(BOOL)fromNotifOpened fromClearAll:(BOOL)fromClearAll;
118125

119-
+ (BOOL)receiveRemoteNotification:(UIApplication* _Nonnull)application UserInfo:(NSDictionary* _Nonnull)userInfo completionHandler:(void (^_Nonnull)(UIBackgroundFetchResult))completionHandler;
120126
+ (void)notificationReceived:(NSDictionary* _Nonnull)messageDict wasOpened:(BOOL)opened;
121-
+ (void)handleWillPresentNotificationInForegroundWithPayload:(NSDictionary * _Nonnull)payload withCompletion:(OSNotificationDisplayResponse _Nonnull)completion;
122-
+ (void)didRegisterForRemoteNotifications:(UIApplication *_Nonnull)app deviceToken:(NSData *_Nonnull)inDeviceToken;
123-
+ (void)handleDidFailRegisterForRemoteNotification:(NSError*_Nonnull)err;
124127
+ (void)checkProvisionalAuthorizationStatus;
128+
+ (void)registerLifecycleObserver;
129+
125130
@end

iOS_SDK/OneSignalSDK/OneSignalNotifications/OSNotificationsManager.m

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -252,9 +252,6 @@ + (void)start {
252252
@selector(onesignalSetApplicationIconBadgeNumber:)
253253
);
254254
[OneSignalNotificationsUNUserNotificationCenter setup];
255-
256-
[self registerLifecycleObserver];
257-
258255
}
259256
#pragma clang diagnostic pop
260257

@@ -653,7 +650,8 @@ + (NSString*)checkForProcessedDups:(NSDictionary*)customDict lastMessageId:(NSSt
653650

654651
+ (void)handleWillPresentNotificationInForegroundWithPayload:(NSDictionary *)payload withCompletion:(OSNotificationDisplayResponse)completion {
655652
// check to make sure the app is in focus and it's a OneSignal notification
656-
if (![OneSignalCoreHelper isOneSignalPayload:payload]
653+
if ([OSPrivacyConsentController shouldLogMissingPrivacyConsentErrorWithMethodName:nil]
654+
|| ![OneSignalCoreHelper isOneSignalPayload:payload]
657655
|| UIApplication.sharedApplication.applicationState == UIApplicationStateBackground) {
658656
completion([OSNotification new]);
659657
return;
@@ -662,10 +660,16 @@ + (void)handleWillPresentNotificationInForegroundWithPayload:(NSDictionary *)pay
662660

663661
OSDisplayableNotification *osNotification = [OSDisplayableNotification parseWithApns:payload];
664662
if ([osNotification additionalData][ONESIGNAL_IAM_PREVIEW]) {
663+
[self notificationReceived:payload wasOpened:NO];
665664
completion(nil);
666665
return;
667666
}
668-
[self handleWillShowInForegroundForNotification:osNotification completion:completion];
667+
668+
OSNotificationDisplayResponse wrappedCompletion = ^(OSNotification *notification) {
669+
[self notificationReceived:payload wasOpened:NO];
670+
completion(notification);
671+
};
672+
[self handleWillShowInForegroundForNotification:osNotification completion:wrappedCompletion];
669673
}
670674

671675
+ (void)handleWillShowInForegroundForNotification:(OSDisplayableNotification *)notification completion:(OSNotificationDisplayResponse)completion {
@@ -801,17 +805,7 @@ + (void)clearBadgeCount:(BOOL)fromNotifOpened fromClearAll:(BOOL)fromClearAll {
801805
return;
802806
}
803807

804-
if (@available(iOS 16.0, *)) {
805-
[[UNUserNotificationCenter currentNotificationCenter] setBadgeCount:0 withCompletionHandler:^(NSError * _Nullable error) {
806-
if (error) {
807-
[OneSignalLog onesignalLog:ONE_S_LL_ERROR message:[NSString stringWithFormat:@"clearBadgeCount encountered error setting badge count: %@", error]];
808-
}
809-
}];
810-
} else {
811-
[OneSignalCoreHelper runOnMainThread:^{
812-
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
813-
}];
814-
}
808+
[self setBadgeCount:0];
815809
}
816810

817811
+ (BOOL)handleIAMPreview:(OSNotification *)notification {
@@ -1000,6 +994,37 @@ + (UNNotificationRequest*)prepareUNNotificationRequest:(OSNotification*)notifica
1000994
return [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger];
1001995
}
1002996

997+
#pragma mark - Manual Integration APIs (for use when swizzling is disabled)
998+
999+
+ (void)handleNotificationResponse:(UNNotificationResponse *)response {
1000+
if ([OSPrivacyConsentController shouldLogMissingPrivacyConsentErrorWithMethodName:nil])
1001+
return;
1002+
if (![OneSignalConfigManager getAppId])
1003+
return;
1004+
if ([@"com.apple.UNNotificationDismissActionIdentifier" isEqual:response.actionIdentifier])
1005+
return;
1006+
if (![OneSignalCoreHelper isOneSignalPayload:response.notification.request.content.userInfo])
1007+
return;
1008+
NSDictionary *userInfo = [OneSignalCoreHelper formatApsPayloadIntoStandard:response.notification.request.content.userInfo
1009+
identifier:response.actionIdentifier];
1010+
[self notificationReceived:userInfo wasOpened:YES];
1011+
}
1012+
1013+
+ (void)setBadgeCount:(NSInteger)badgeCount {
1014+
[OneSignalBadgeHelpers updateCachedBadgeValue:badgeCount usePreviousBadgeCount:false];
1015+
if (@available(iOS 16.0, *)) {
1016+
[[UNUserNotificationCenter currentNotificationCenter] setBadgeCount:badgeCount withCompletionHandler:^(NSError * _Nullable error) {
1017+
if (error) {
1018+
[OneSignalLog onesignalLog:ONE_S_LL_ERROR message:[NSString stringWithFormat:@"setBadgeCount encountered error setting badge count: %@", error]];
1019+
}
1020+
}];
1021+
} else {
1022+
[OneSignalCoreHelper runOnMainThread:^{
1023+
[UIApplication sharedApplication].applicationIconBadgeNumber = badgeCount;
1024+
}];
1025+
}
1026+
}
1027+
10031028
- (void)dealloc {
10041029
[OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:@"OSNotificationsManager observer deallocated"];
10051030
[[NSNotificationCenter defaultCenter] removeObserver:self];

iOS_SDK/OneSignalSDK/Source/OneSignal.m

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -749,9 +749,11 @@ + (void)onSessionEnding:(NSArray<OSInfluence *> *)lastInfluences {
749749
#pragma clang diagnostic ignored "-Wincomplete-implementation"
750750
@implementation UIApplication (OneSignal)
751751
+ (void)load {
752+
[OSDialogInstanceManager setSharedOSDialogInstance:[OneSignalDialogController sharedInstance]];
753+
[OSNotificationsManager registerLifecycleObserver];
752754

753-
if ([self shouldDisableBasedOnProcessArguments]) {
754-
[OneSignalLog onesignalLog:ONE_S_LL_WARN message:@"OneSignal method swizzling is disabled. Make sure the feature is enabled for production."];
755+
if ([self shouldDisableSwizzling]) {
756+
[OneSignalLog onesignalLog:ONE_S_LL_WARN message:@"OneSignal method swizzling is disabled via Info.plist. Developers must manually forward notification delegate methods to OneSignal."];
755757
return;
756758
}
757759
[OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:@"UIApplication(OneSignal) LOADED!"];
@@ -784,8 +786,6 @@ + (void)load {
784786
[[OSMigrationController new] migrate];
785787
// sessionLaunchTime = [NSDate date];
786788
// TODO: sessionLaunchTime used to always be set in load
787-
788-
[OSDialogInstanceManager setSharedOSDialogInstance:[OneSignalDialogController sharedInstance]];
789789
}
790790

791791
/*
@@ -797,8 +797,9 @@ - (void)onesignalSetApplicationIconBadgeNumber:(NSInteger)badge {
797797
[self onesignalSetApplicationIconBadgeNumber:badge];
798798
}
799799

800-
+(BOOL) shouldDisableBasedOnProcessArguments {
801-
if ([NSProcessInfo.processInfo.arguments containsObject:@"DISABLE_ONESIGNAL_SWIZZLING"]) {
800+
+ (BOOL)shouldDisableSwizzling {
801+
id plistValue = [[NSBundle mainBundle] objectForInfoDictionaryKey:ONESIGNAL_DISABLE_SWIZZLING];
802+
if (plistValue != nil && [plistValue boolValue]) {
802803
return YES;
803804
}
804805
return NO;

0 commit comments

Comments
 (0)