Skip to content

Commit 04486aa

Browse files
authored
Add Authorization Options for Provisional Notifications (#442)
* Add Authorization Options for Provisional Notifications • When using provisional notifications, when a user receives a notifications and taps 'Deliver Prominently', they should be able to receive normal notifications with sound, badge, etc. • However it appears that with the current SDK, when a user taps 'Deliver Prominently', the notifications don't make sounds/badges until the user opens the app again. • This can be fixed by requesting full authorization options immediately when registering for provisional notifications * Fix Permission State • The last commit did not correctly detect the new value for provisional notifications' UNAuthorizationOption in the UNUserNotificationCenter+OneSignal category requestAuthorizationWithOptions swizzle. • This resulted in the permission state not getting updated correctly and caused tests to fail. * Correctly Check for Enum Membership • We have a swizzled implementation of requestAuthorizationWithOptions: in case developers call it directly instead of using our SDK's prompt methods • We needed to check if the app was requesting provisional authorization which would cause the prompt not to be shown. • However we were incorrectly evaluating equality of the raw value for the provisional authorization enum case instead of checking for enum membership (which would be a bitmask that could potentially contain multiple cases)
1 parent 9f455db commit 04486aa

File tree

4 files changed

+16
-5
lines changed

4 files changed

+16
-5
lines changed

iOS_SDK/OneSignalSDK/Source/OneSignalCommonDefines.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@
5959
#define PROVISIONAL_UNAUTHORIZATIONOPTION (UNAuthorizationOptions)(1 << 6)
6060
#define PROVIDES_SETTINGS_UNAUTHORIZATIONOPTION (UNAuthorizationOptions)(1 << 5)
6161

62+
// These options are defined in all versions of iOS that we support, so we
63+
// can use them directly.
64+
#define DEFAULT_UNAUTHORIZATIONOPTIONS (UNAuthorizationOptionSound + UNAuthorizationOptionBadge + UNAuthorizationOptionAlert)
65+
6266
// iOS Parameter Names
6367
#define IOS_USES_PROVISIONAL_AUTHORIZATION @"uses_provisional_auth"
6468
#define IOS_REQUIRES_EMAIL_AUTHENTICATION @"require_email_auth"

iOS_SDK/OneSignalSDK/Source/OneSignalNotificationSettingsIOS10.m

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,16 +176,18 @@ - (void)registerForProvisionalAuthorization:(void(^)(BOOL accepted))completionHa
176176

177177
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
178178

179+
let options = PROVISIONAL_UNAUTHORIZATIONOPTION + DEFAULT_UNAUTHORIZATIONOPTIONS;
180+
179181
id responseBlock = ^(BOOL granted, NSError *error) {
180182
[OneSignalHelper dispatch_async_on_main_queue:^{
181-
OneSignal.currentPermissionState.provisional = granted;
182-
[OneSignal updateNotificationTypes: granted ? PROVISIONAL_UNAUTHORIZATIONOPTION : 0];
183+
OneSignal.currentPermissionState.provisional = true;
184+
[OneSignal updateNotificationTypes: options];
183185
if (completionHandler)
184186
completionHandler(granted);
185187
}];
186188
};
187189

188-
[center requestAuthorizationWithOptions:PROVISIONAL_UNAUTHORIZATIONOPTION completionHandler:responseBlock];
190+
[center requestAuthorizationWithOptions:options completionHandler:responseBlock];
189191
}
190192

191193
// Ignore these 2 events, promptForNotifications: already takes care of these.

iOS_SDK/OneSignalSDK/Source/UNUserNotificationCenter+OneSignal.m

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,12 @@ + (void)setUseiOS10_2_workaround:(BOOL)enable {
9494
static BOOL useCachedUNNotificationSettings;
9595
static UNNotificationSettings* cachedUNNotificationSettings;
9696

97+
// This is a swizzled implementation of requestAuthorizationWithOptions:
98+
// in case developers call it directly instead of using our prompt method
9799
- (void)onesignalRequestAuthorizationWithOptions:(UNAuthorizationOptions)options completionHandler:(void (^)(BOOL granted, NSError *__nullable error))completionHandler {
98100

99-
BOOL notProvisionalRequest = options != PROVISIONAL_UNAUTHORIZATIONOPTION;
101+
// check options for UNAuthorizationOptionProvisional membership
102+
BOOL notProvisionalRequest = (options & PROVISIONAL_UNAUTHORIZATIONOPTION) == 0;
100103

101104
//we don't want to modify these settings if the authorization is provisional (iOS 12 'Direct to History')
102105
if (notProvisionalRequest)

iOS_SDK/OneSignalSDK/UnitTests/ProvisionalAuthorizationTests.m

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,9 @@ - (void)testProvisionalPermissionState {
8484

8585
[UnitTestCommonMethods runBackgroundThreads];
8686

87-
XCTAssertTrue(UNUserNotificationCenterOverrider.lastRequestedAuthorizationOptions == PROVISIONAL_UNAUTHORIZATIONOPTION);
87+
let options = PROVISIONAL_UNAUTHORIZATIONOPTION + DEFAULT_UNAUTHORIZATIONOPTIONS;
88+
89+
XCTAssertTrue(UNUserNotificationCenterOverrider.lastRequestedAuthorizationOptions == options);
8890

8991
XCTAssertTrue(observer->last.to.provisional);
9092
XCTAssertFalse(observer->last.from.provisional);

0 commit comments

Comments
 (0)