1

I'm a total noobie coming to OSX cocoa programming from php, and am having a lot of trouble with NSTimer. I'm trying to create an application that keeps a user-specified duration timer running in the background and then does something when that timer expires (like a countdown timer).

When its in the foreground my application works as it should. But if it goes into the background (ie: I click on another application window), the timer becomes entirely erroneous, and the countdown seems to progress on an ad hoc basis. Then, once I re-focus on this application, the timer seems to re-start. But if the pre-specified amount of time has elapsed while the application is in background, the application doesn't know it.

Here is the basic code I'm calling from within the main run loop:

self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateStatus) userInfo:nil repeats:YES];

-(void) updateStatus {
   if([self.totalSeconds]>0) {
      self.totalSeconds=self.totalSeconds-1;
   } else {
      //perform end of timer methods
   }
}

What am I doing wrong?

Thanks in advance for your time / assistance.

-M

  • Despite reading through this question here: https://stackoverflow.com/questions/6031651/check-a-condition-in-the-background-every-ten-seconds-and-send-notification I still can't get this to work. Any advice / guidance is most appreciated! – user3643251 May 16 '14 at 04:19
  • 1
    If OS 10.9 App Nap can suspend the timers. https://developer.apple.com/library/mac/releasenotes/MacOSX/WhatsNewInOSX/Articles/MacOSX10_9.html#//apple_ref/doc/uid/TP40013207-CH100 – 9dan May 16 '14 at 04:21
  • Yes: am developing for 10.7 and above, but testing on 10.9... What can I do in 10.9 to prevent the AppNap from suspending the timers? And, regarding Matt's answer below, will comparing NSDate values even work if the timers have been suspended because the app is in the background? – user3643251 May 16 '14 at 04:25
  • 1
    I'd search SO with 'beginActivityWithOptions' keyword. – 9dan May 16 '14 at 04:26
  • Of course comparing NSDate values will work: _time_ is not slowed when your app is the background! The computer's clock still works fine. What might not happen is that your timer might not fire very often to tell you to _check_ the time (unless you do something about it). – matt May 16 '14 at 04:30
  • possible duplicate of [OS X Cocoa timer not fired when application on background](http://stackoverflow.com/questions/20607290/os-x-cocoa-timer-not-fired-when-application-on-background) – matt May 16 '14 at 04:34
  • Please search before asking. – matt May 16 '14 at 04:36
  • Thanks for the redirect... I've literally spent hours searching for a solution to this (again, a noobie to cocoa). Will try this and see what happens. Curious if NSTimer isn't the best route to go with this problem, though. Thanks for your time / help. – user3643251 May 16 '14 at 04:40

1 Answers1

1

You can't rely on the timing of a timer (especially when you're running in the background). You can use the timer as a cue to look at what time it is, but the way you're going to decide how much time has elapsed in the real world is not by decrementing an integer, but by storing the original time in an instance variable and comparing the time it is now. (Look at NSDate to see how to do that.)

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Matt: Thanks for your response. Quick additional question: am I guaranteed that the timer method will fire at all with the app in the background, or will it happen only if the user brings the application back to front / focus? – user3643251 May 16 '14 at 04:21
  • You're just making me repeat myself. I already said: You're not guaranteed of anything ever about timers. And certainly not what they will do in the background. – matt May 16 '14 at 04:29
  • Interesting... So if timers aren't a clear way to go about this application, what other tools are available to me? What am I missing about this? It seems straightforward: do X in 65 seconds... regardless of whether the app is in background or not... Any ideas? – user3643251 May 16 '14 at 04:31
  • That would be a different question. I tried to answer the question you _did_ ask. If you therefore have another question, _ask_ another question (as a new Stack Overflow question). – matt May 16 '14 at 04:32
  • Asked this new here: https://stackoverflow.com/questions/23692722/how-to-execute-function-in-x-seconds-regardless-of-whether-app-is-in-background – user3643251 May 16 '14 at 04:37