diff --git a/iOS_SDK/OneSignalSDK/Source/OneSignalLifecycleObserver.m b/iOS_SDK/OneSignalSDK/Source/OneSignalLifecycleObserver.m index dca56703b..b3ef24852 100644 --- a/iOS_SDK/OneSignalSDK/Source/OneSignalLifecycleObserver.m +++ b/iOS_SDK/OneSignalSDK/Source/OneSignalLifecycleObserver.m @@ -90,7 +90,7 @@ - (void)didBecomeActive { - (void)willResignActive { [OneSignal onesignalLog:ONE_S_LL_VERBOSE message:@"application/scene willResignActive"]; - + [OneSignalTracker willResignActiveTriggered]; if ([OneSignal appId]) { [OneSignalTracker onFocus:YES]; [OneSignal sendTagsOnBackground]; @@ -99,7 +99,7 @@ - (void)willResignActive { - (void)didEnterBackground { [OneSignal onesignalLog:ONE_S_LL_VERBOSE message:@"application/scene didEnterBackground"]; - + [OneSignalTracker didEnterBackgroundTriggered]; if ([OneSignal appId]) [OneSignalLocation onFocus:NO]; } diff --git a/iOS_SDK/OneSignalSDK/Source/OneSignalTracker.h b/iOS_SDK/OneSignalSDK/Source/OneSignalTracker.h index 2c7520658..ad4888a06 100644 --- a/iOS_SDK/OneSignalSDK/Source/OneSignalTracker.h +++ b/iOS_SDK/OneSignalSDK/Source/OneSignalTracker.h @@ -31,5 +31,7 @@ + (void)onFocus:(BOOL)toBackground; + (void)onSessionEnded:(NSArray *) lastInfluences; ++ (void)willResignActiveTriggered; ++ (void)didEnterBackgroundTriggered; @end diff --git a/iOS_SDK/OneSignalSDK/Source/OneSignalTracker.m b/iOS_SDK/OneSignalSDK/Source/OneSignalTracker.m index 547201676..946a2f0ec 100644 --- a/iOS_SDK/OneSignalSDK/Source/OneSignalTracker.m +++ b/iOS_SDK/OneSignalSDK/Source/OneSignalTracker.m @@ -58,18 +58,29 @@ @implementation OneSignalTracker static UIBackgroundTaskIdentifier focusBackgroundTask; static NSTimeInterval lastOpenedTime; static BOOL lastOnFocusWasToBackground = YES; +static BOOL willResignActiveTriggered = NO; +static BOOL didEnterBackgroundTriggered = NO; + (void)resetLocals { [OSFocusTimeProcessorFactory resetUnsentActiveTime]; - focusBackgroundTask = 0; + focusBackgroundTask = 0; lastOpenedTime = 0; lastOnFocusWasToBackground = YES; + [self resetBackgroundDetection]; } + (void)setLastOpenedTime:(NSTimeInterval)lastOpened { lastOpenedTime = lastOpened; } ++ (void)willResignActiveTriggered { + willResignActiveTriggered = YES; +} + ++ (void)didEnterBackgroundTriggered { + didEnterBackgroundTriggered = YES; +} + + (void)beginBackgroundFocusTask { focusBackgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ [OneSignalTracker endBackgroundFocusTask]; @@ -81,10 +92,26 @@ + (void)endBackgroundFocusTask { focusBackgroundTask = UIBackgroundTaskInvalid; } +/** + Returns true if application truly did come from a backgrounded state. + Returns false if the application bypassed `didEnterBackground` after entering `willResignActive`. + This can happen if the app resumes after a native dialog displays over the app or after the app is in a suspended state and not backgrounded. +**/ ++ (BOOL)applicationForegroundedFromBackgroundedState { + return !(willResignActiveTriggered && !didEnterBackgroundTriggered); +} + ++ (void)resetBackgroundDetection { + willResignActiveTriggered = NO; + didEnterBackgroundTriggered = NO; +} + + (void)onFocus:(BOOL)toBackground { // return if the user has not granted privacy permissions - if ([OneSignal requiresUserPrivacyConsent]) + if ([OneSignal requiresUserPrivacyConsent]) { + [self resetBackgroundDetection]; return; + } // Prevent the onFocus to be called twice when app being terminated // - Both WillResignActive and willTerminate @@ -101,6 +128,10 @@ + (void)onFocus:(BOOL)toBackground { + (void)applicationForegrounded { [OneSignal onesignalLog:ONE_S_LL_DEBUG message:@"Application Foregrounded started"]; + + BOOL fromBackgroundedState = [self applicationForegroundedFromBackgroundedState]; + [self resetBackgroundDetection]; + [OSFocusTimeProcessorFactory cancelFocusCall]; if (OneSignal.appEntryState != NOTIFICATION_CLICK) @@ -115,7 +146,10 @@ + (void)applicationForegrounded { // This checks if notification permissions changed when app was backgrounded [OneSignal sendNotificationTypesUpdate]; [[OSSessionManager sharedSessionManager] attemptSessionUpgrade:OneSignal.appEntryState]; - [OneSignal receivedInAppMessageJson:nil]; + if (fromBackgroundedState) { + // Use cached IAMs if app truly went into the background + [OneSignal receivedInAppMessageJson:nil]; + } } let wasBadgeSet = [OneSignal clearBadgeCount:false];