Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 35 additions & 7 deletions iOS_SDK/OneSignalSDK/Source/OneSignal.m
Original file line number Diff line number Diff line change
Expand Up @@ -1561,12 +1561,15 @@ + (BOOL)shouldRegisterNow {
return false;

// Don't make a 2nd on_session if have in inflight one
onesignal_Log(ONE_S_LL_VERBOSE, [NSString stringWithFormat:@"shouldRegisterNow:waitingForOneSReg: %d", waitingForOneSReg]);
if (waitingForOneSReg)
return false;

onesignal_Log(ONE_S_LL_VERBOSE, [NSString stringWithFormat:@"shouldRegisterNow:isImmediatePlayerCreateOrOnSession: %d", [self isImmediatePlayerCreateOrOnSession]]);
if ([self isImmediatePlayerCreateOrOnSession])
return true;

onesignal_Log(ONE_S_LL_VERBOSE, [NSString stringWithFormat:@"shouldRegisterNow:isOnSessionSuccessfulForCurrentState: %d", isOnSessionSuccessfulForCurrentState]);
if (isOnSessionSuccessfulForCurrentState)
return false;

Expand All @@ -1587,6 +1590,7 @@ + (BOOL)shouldRegisterNow {
}

+ (void)registerUserAfterDelay {
[OneSignal onesignal_Log:ONE_S_LL_VERBOSE message:@"registerUserAfterDelay"];
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(registerUser) object:nil];
[OneSignalHelper performSelector:@selector(registerUser) onMainThreadOnObject:self withObject:nil afterDelay:reattemptRegistrationInterval];
}
Expand All @@ -1601,21 +1605,44 @@ + (void)registerUser {
// return if the user has not granted privacy permissions
if ([self shouldLogMissingPrivacyConsentErrorWithMethodName:nil])
return;

// We should delay registration if we are waiting on APNS
// But if APNS hasn't responded within 30 seconds,
// we should continue and register the user.
if (waitingForApnsResponse && initializationTime && [[NSDate date] timeIntervalSinceDate:initializationTime] < maxApnsWait) {

if ([self shouldRegisterUserAfterDelay]) {
[self registerUserAfterDelay];
return;
}

if (!serialQueue)
serialQueue = dispatch_queue_create("com.onesignal.regiseruser", DISPATCH_QUEUE_SERIAL);

dispatch_async(serialQueue, ^{
[self registerUserNow];
}

+(void)registerUserNow {
[OneSignal onesignal_Log:ONE_S_LL_VERBOSE message:@"registerUserNow"];

if (!serialQueue)
serialQueue = dispatch_queue_create("com.onesignal.regiseruser", DISPATCH_QUEUE_SERIAL);

dispatch_async(serialQueue, ^{
[self registerUserInternal];
});
});
}

// We should delay registration if we are waiting on APNS
// But if APNS hasn't responded within 30 seconds (maxApnsWait),
// we should continue and register the user.
+ (BOOL)shouldRegisterUserAfterDelay {
[OneSignal onesignal_Log:ONE_S_LL_VERBOSE message:[NSString stringWithFormat:@"registerUser:waitingForApnsResponse: %d", waitingForApnsResponse]];
[OneSignal onesignal_Log:ONE_S_LL_VERBOSE message:[NSString stringWithFormat:@"registerUser:initializationTime: %@", initializationTime]];

// If there isn't an initializationTime yet then the SDK hasn't finished initializing so we should delay
if (!initializationTime)
return true;

if (!waitingForApnsResponse)
return false;

return [[NSDate date] timeIntervalSinceDate:initializationTime] < maxApnsWait;
}

+ (OSUserState *)createUserState {
Expand Down Expand Up @@ -1697,6 +1724,7 @@ + (OSUserState *)createUserState {
}

+ (void)registerUserInternal {
[OneSignal onesignal_Log:ONE_S_LL_VERBOSE message:@"registerUserInternal"];
_registerUserFinished = false;

// return if the user has not granted privacy permissions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ + (void)setDidFailRegistarationErrorCode:(NSInteger)value {
}

+ (void)setBlockApnsResponse:(BOOL)block {
blockApnsResponse = true;
blockApnsResponse = block;
}

+ (void)setAPNSTokenLength:(int)tokenLength {
Expand Down
29 changes: 29 additions & 0 deletions iOS_SDK/OneSignalSDK/UnitTests/UnitTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,35 @@ - (void)testPromptedButNeveranswerNotificationPrompt {
XCTAssertEqualObjects(OneSignalClientOverrider.lastHTTPRequest[@"notification_types"], @-19);
}

// This test covers migrating to OneSignal with the following senario;
// 1. App was released publicly to the AppStore with push on with another provider.
// 2. User imports all existing push tokens into OneSignal.
// 3. OneSignal is added to their app.
// 4. Ensure that identifier is always send with the player create, to prevent duplicated players
- (void)testNotificationPermissionsAcceptedBeforeAddingOneSiganl_waitsForAPNSTokenBeforePlayerCreate {
// 1. Set that notification permissions are already enabled.
UNUserNotificationCenterOverrider.notifTypesOverride = 7;
UNUserNotificationCenterOverrider.authorizationStatus = [NSNumber numberWithInteger:UNAuthorizationStatusAuthorized];

// 2. Setup delay of APNs reaponse
[UIApplicationOverrider setBlockApnsResponse:true];

// 3. Init OneSignal
[UnitTestCommonMethods initOneSignal_andThreadWait];
[NSObjectOverrider runPendingSelectors];

// 4. Don't make a network call right away
XCTAssertNil(OneSignalClientOverrider.lastHTTPRequest);

// 5. Simulate APNs now giving us a push token
[UIApplicationOverrider setBlockApnsResponse:false];
[UnitTestCommonMethods runBackgroundThreads];

// 6. Ensure we registered with push token and it has the correct notification_types
XCTAssertEqualObjects(OneSignalClientOverrider.lastHTTPRequest[@"notification_types"], @15);
XCTAssertEqualObjects(OneSignalClientOverrider.lastHTTPRequest[@"identifier"], @"0000000000000000000000000000000000000000000000000000000000000000");
}

- (void)testNotificationTypesWhenAlreadyAcceptedWithAutoPromptOffOnFristStartPreIos10 {
OneSignalHelperOverrider.mockIOSVersion = 9;
[UnitTestCommonMethods setCurrentNotificationPermission:true];
Expand Down