I’m looking at Sam’s Teach Yourself iPhone dev and I don’t understand the example given for backgrounding. The non backgrounding code is:
- (void)viewDidLoad {
[super viewDidLoad];
count=0;
theTimer=[NSTimer scheduledTimerWithTimeInterval:0.1
target:self
selector:@selector(countUp)
userInfo:nil
repeats:YES];
}
And the backgrounding version is:
- (void)viewDidLoad {
[super viewDidLoad];
counterTask = [[UIApplication sharedApplication]
beginBackgroundTaskWithExpirationHandler:^{
// If you're worried about exceeding 10 minutes, handle it here
}];
count=0;
theTimer=[NSTimer scheduledTimerWithTimeInterval:0.1
target:self
selector:@selector(countUp)
userInfo:nil
repeats:YES];
}
What I don’t understand is where the associated is between the activity to be performed in the background and beginBackgroundTaskWithExpirationHandler.
In this example the the NSTimer is running in the background – but what if there was some other activity to be performed in the background as well i.e. suppose the code is:
- (void)viewDidLoad {
[super viewDidLoad];
counterTask = [[UIApplication sharedApplication]
beginBackgroundTaskWithExpirationHandler:^{
// If you're worried about exceeding 10 minutes, handle it here
}];
count=0;
theTimer=[NSTimer scheduledTimerWithTimeInterval:0.1
target:self
selector:@selector(countUp)
userInfo:nil
repeats:YES];
x: some other activity to be performed in the background
maybe another timer with a difference time interval
}
How could you additionally specify that x also gets executed in the background?
Or have I misunderstood how it works and when beginBackgrounTaskWithExpirationHandler is called it is the the whole of the application whcih will in fact execute in the background? If that is the case then why is a task identifier necessary as you would only be able to start one task which is your app?
If that’s not the case and it is possible to pick and choose different tasks to execute in the background, then how is this implemented? Suppose in this example X is a second timer with a different interval and a different expiration condition, what would the code look like if I wanted both theTimer and x to execute in the background? In other words what if the code was this:
- (void)viewDidLoad {
[super viewDidLoad];
counterTask = [[UIApplication sharedApplication]
beginBackgroundTaskWithExpirationHandler:^{
// If you're worried about exceeding 10 minutes, handle it here
}];
count=0;
theTimer=[NSTimer scheduledTimerWithTimeInterval:0.1
target:self
selector:@selector(countUp)
userInfo:nil
repeats:YES];
theTimer2=[NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(aDifferentMethod)
userInfo:nil
repeats:YES];
theTimer3=[NSTimer scheduledTimerWithTimeInterval:10.0
target:self
selector:@selector(anotherDifferentMethod)
userInfo:nil
repeats:YES];
}
How to specify that both theTimer and theTimer2 execute in the background but theTimer3 doesn’t?
The whole application will run. It’s up to you to determine what to do or not do. The point of
beginBackgroundTaskWithExpirationHandler:is that it tells the system that you have some long-running thing to do. It makes a note, and hands you back a token. When your long running task is finished, you callendBackgroundTask:with that token. It’s possible that during that time, you never actually went into the background.When your application is going to be suspended, the system looks to see if you have any pending tokens. If you don’t, then it just suspends you. If you do, then it lets you run for a while more. The system doesn’t care how you associate those tokens with work. You could just use a single token for your entire program. Or each object could keep its own token when it needed to do something. The point is that as long as you have one token, you’re generally going to be given some extra time to work before being suspended.
To your question about timers, you generally shouldn’t do any timer work in the background. You don’t have a lot of time (10 minutes at most). You need to do your work and get out. You should be suspending (invalidating) all your timers when you go in the background. You then set them back up when you resume.