Understanding Various Application States

Discussion in 'iOS Programming' started by MaxFreud, Feb 23, 2011.

  1. MaxFreud macrumors newbie

    Jan 5, 2011
    Hi all,

    I'll try making this as easy to read as possible. For a TLDR just look at the question below.

    Problem Background
    I am making a very simple countdown timer app, and I want to ensure that the timer label shows the right time if the app goes to sleep or the phone is locked and then the user returns to the app.

    Here's what I do:
    • Inside of applicationWillResignActive: I save the current time using
      sleepTime = [[NSDate alloc] init];	
      NSLog(@"Going to bed... Time is %@", [sleepTime description]);
    • Inside of applicationDidBecomeActive: I do
      wakeTime = [[NSDate alloc] init];
      [mainViewController setTimeLeft:[wakeTime timeIntervalSinceDate:sleepTime]];
      NSLog(@"Waking up... Time is %@", [wakeTime description]);	
    • In mainViewController, there is a timer
      timer = [[NSTimer alloc] initWithFireDate:[NSDate date] interval:1 target:self selector:@selector(oneSecondPassed:) userInfo:nil repeats:YES];
      [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
      and an int variable called timeLeft which is the number of seconds that is displayed on the screen and gets decremented every time the timer fires.

    The problem is that sometimes the correct time is not getting displayed after returning to the app. I tested several times on my phone and looked at the console logs, and I think the problem occurs when the OS goes into a "low power" state.
    For example, if I lock the phone, I see from the console output that applicationWillResignActive: was called but the timer keeps firing (as indicated by the continuing output of the oneSecondPassed: method. However, at some point, I get this:
    Wed Feb 23 12:09:08 unknown CommCenter[31] <Notice>: Telling CSI to go low power.
    Wed Feb 23 12:09:08 unknown CommCenter[31] <Notice>: CSI can enter low power, so now telling to do so.
    After this, the output of oneSecondPassed: (the selector called on the timer fire events) ceases until my local notification brings things out of the low power state.

    From the developer videos, I understand that an application may have one of 5 states:
    1. Foreground, Active
    2. Foreground, Inactive
    3. Not Running
    4. Background, Running
    5. Background, Suspended

    Now I don't understand which one of these is the low power state, and which one my app is in when I lock the phone and it's still logging timer messages. More confusing is the fact that, from the logs, when the phone goes into the low power state, applicationWillResignActive: has already been called, but applicationDidEnterBackground: is never called and there is no log message from it.
    Can someone please explain to me how the above states (and the the corresponding transitional application delegate) relate to the phone's low power state? In addition to this low power state, are there other changes in the application activity that I would have to account for?

    Thanks for your time,
  2. PhoneyDeveloper macrumors 68040


    Sep 2, 2008
    Why don't you just save the start time and then each time the timer fires get the current time and do the subtraction to display the time remaining? You really can't rely on the timer to fire exactly every second anyway.
  3. MaxFreud thread starter macrumors newbie

    Jan 5, 2011
    I know I can make the timer work. The purpose of my post was understanding what's going on because some state is clearly changing without letting my application delegate know.
  4. MaxFreud thread starter macrumors newbie

    Jan 5, 2011
    Ok. In fact, I shouldn't have even included all that rambling. I apologize.

    Here is my question concisely:
    If an app is running and the user locks the phone, it keeps running. For how long? And/or what things can happen to stop it from running? What state is it in (foreground, background, (in)active, etc.)?

Share This Page