2

I am creating puzzle game application and in that I am displaying time (i.e 01:20) using NSTimer. NSTimer is paused when application gone in background but i want to continue it even application is in background state.

for example timer count is 15 sec when app gone in background and I put it for 5 sec and become in foreground now I need to timer count changes to 20 sec

I have searched a lot but didn't get good answer. So Please suggest me how can I achieve this.

Raj
  • 637
  • 13
  • 32

5 Answers5

4

Don't think of a timer as an object for timing something. Think of it rather as an object that pulses at a given frequency. To measure time, record a start time and compare it to the current time.

To record the start time, write it to a file as follows, probably in appWillResignActive:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
NSString *filename = [path stringByAppendingPathComponent:@"saveme.dat"];

NSData * data = [NSKeyedArchiver archivedDataWithRootObject:self.startDate];
[data writeToFile:filename atomically:NO];
// invalidate timer

When appWillBecomeActive:

NSData *data = [NSData dataWithContentsOfFile:filename];    // using the same code as before
self.startDate = [NSKeyedUnarchiver unarchiveObjectWithData:data];
// start a timer for the purpose of pulsing only

Elapsed time at this point is:

NSDate *now = [NSDate date];
NSTimeInterval = [now timeIntervalSinceDate:self.startDate];

All of the foregoing can be done without running in the background. If you really need a timer to fire in the background, see this apple ref. Under "Background Execution". In a nutshell, you can do it, but Apple will make you meet several criteria before approving the app -- like it must be finite and provide utility for the user.

danh
  • 62,181
  • 10
  • 95
  • 136
  • but I am firing some query after some period of time. which is depends on NSTimer. for e.g. after 20 sec i am firing query and my app is in background state when timer count is 15 sec. and it became active after 30 sec . Now I need is to update that timer count by 15 sec to 45 sec and need to fire query for 2 time. – Raj Apr 03 '13 at 15:15
  • I see. I made a small edit. Can you find a way to do those queries after you reawaken? It's a lot simpler (and more likely to get approved) if you avoid background running. – danh Apr 03 '13 at 15:29
  • Why are you not using `NSUserDefaults`? – rebellion Nov 02 '14 at 09:12
1

You're going to need to write that information out to a file or cache the time at exit. Then when the application resumes you read that value in, do some math, and restart your timer.

In your AppDelegate as the app is going to background save the time to a file or NSUserDefaults. You can call NSDate's class method to get an Integer value you can easily store.

+ (NSTimeInterval)timeIntervalSinceReferenceDate

At application resume, read in the value. Get the current timeIntervalSinceReferenceDate and subtract. You should have the number of seconds that have elapsed.

Cameron Lowell Palmer
  • 21,528
  • 7
  • 125
  • 126
1

Create a NSDate ivar in your class to manage the starting time.

@implementation SomeClass {
  NSDate *startTime;
}

For your timer, simply calculate the time through math on this date. Your timer is more used to invoke the method that does this calculation rather than determine the time itself...

[NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(updateTimer) userInfo:nil repeats:YES];

Logic for your method...

- (void)updateTimer {
  if (!startTime) {
    startTime = [NSDate date];
  }
  NSInteger secondsSinceStart = -(NSInteger)[startTime timeIntervalSinceNow];
  NSLog(@"%d", secondsSinceStart);
}
Ben M
  • 2,405
  • 1
  • 20
  • 19
0

I would recommend saving the start time as an NSDate object, and then having an NSTimer that, every second while the app is running, updates the displayed time by calculating the time interval between the current time and the start time. Pause the timer when your app goes into the background (so that you don't get a lot of unnecessary fires when your app starts back up) and restart it whenever the app enters the foreground.

If you want the data to be preserved across the app shutting completely (by being left in the background for too long, or closed in the app switcher) then you'll need to save data to disk at appropriate times.

drewmm
  • 737
  • 6
  • 17
0
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.5f
                                 target:self
                               selector:@selector(showTime)
                               userInfo:NULL
                                repeats:YES];

- (void)showTime
{
NSDate *now=[NSDate date];
NSDateFormatter *dateFormatter=[NSDateFormatter new];
[dateFormatter setDateFormat:@"HH:mm:ss"];
timeLabel.text=[dateFormatter stringFromDate:now];
}

Hope this answer will help you....

Chirag Pipaliya
  • 1,281
  • 12
  • 20