0

I've been able to reproduce a defect in our app twice, but most times I fail. So I'm trying to understand what could possibly be going on here and hopefully have some new things to try. Our app times out and logs the user out after 10 minutes using an NSTimer. Every time the screen is touched the timer is reset, this all works great.

When the user backgrounds the app and comes back, the following code gets called:

- (BOOL)sessionShouldTimeOut {
    if (self.timeoutManager) {
        NSTimeInterval timeIntervalSinceNow = [self.timeoutManager.updateTimer.fireDate timeIntervalSinceDate:[NSDate date]];

        if (timeIntervalSinceNow < 0) {
            return YES;
        } else {
            return NO;
        }

    }
    return NO;
}

- (void)timeoutIfSessionShouldTimeOut {
    if ([self sessionShouldTimeOut]) {
        [self.timeoutManager sendNotificationForTimeout];
    }
}

This (I suspect) is the code that's failing. What happens when it fails is the user logs in, hits the home page and locks their phone. After 10+ minutes, they unlock and the app isn't logged out. When they come back, it's the code above that gets executed to log the user out, but in some scenarios it fails - leaving the user still on the homepage when they shouldn't be.

Here's my current theories I'm trying to test:

  • The timer somehow fires in the background, which then runs the logout routine, but since we're in the background the UI isn't updated but the timer is invalidated (we invalidate the timer after logout) I'm not sure if UI code called from the background will be shown after the app is in the foreground, so this may not be a possibility.

  • The user actually is coming back a few seconds before the timer fires, then after a few seconds when it should have fired it doesn't since it was backgrounded for 10 minutes. Do timers continue to hit their original fire time if the app goes to the background?

  • Somehow, while in the background, self.timeoutManager, updateTimer, or fireDate are being released and set to nil, causing the sessionShouldTimeOut method to return NO. Can variables be nilled in the background? What would cause them to if they could be?

  • The logout routine gets run while the phone is taking a while to actually move to the app, potentially causing the UI updates to not be reflected?

I'm very open to other theories, as you can see a lot of mine are very very edge case since I'm not sure at all what's happening.

I'd appreciate any guidance anyone can offer as to what else I may be able to try, or even any insights into the underworkings of NSTimer or NSRunLoop that may be helpful in this scenario (the documentation on those is terrible for the questions I have)

Bill L
  • 2,576
  • 4
  • 28
  • 55
  • 1
    The important thing to know is if `self.timeoutManager != nil` and if so what the `fireDate` of it's `NSTimer` is. More logging should do that. – trojanfoe May 12 '16 at 14:52
  • Could you think of a scenario that would cause `self.timeoutManager` and `fireDate` to be nilled out while in the background? Low memory, or some other type of scenario that may cause iOS to release those objects? Because normally. the logic works perfectly fine, `self.timeoutManager` isn't nil and `fireDate` is 10 minutes from the last touch and it logs out fine, it's only on some sort of very specific scenario I'm trying to nail down. – Bill L May 12 '16 at 15:41
  • No, objects should not be released while in the background, so I would imagine it's not that. – trojanfoe May 12 '16 at 16:17

1 Answers1

0

In AppDelegate.h set applicationDidEnterBackground:

UIBackgroundTaskIdentifier locationUpdater =[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
         [[UIApplication sharedApplication] endBackgroundTask:locationUpdater];
        locationUpdater=UIBackgroundTaskInvalid;
     } ];

This tells the os that you still have things going and not to stop it.

Ahmed Abdallah
  • 2,338
  • 1
  • 19
  • 30
  • We don't want the timer to run in the background, unfortunately. We want to use the fire date to see if its been 10 minutes every time the app comes back from the background – Bill L May 12 '16 at 17:40