The biggest part of the answer is the technique documented by my colleague @csexton in another answer to this question.
In order to solve the second problem of only getting 10 seconds of ranging time after a transition, you can request additional time to keep ranging. iOS allows you to continue ranging in the background for up to 180 seconds. This requires no background modes and no special permission from the AppStore.
Here's how you set that up:
- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
if (_inBackground) {
[self extendBackgroundRunningTime];
}
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[self logString: [NSString stringWithFormat:@"applicationDidEnterBackground"]];
[self extendBackgroundRunningTime];
_inBackground = YES;
}
- (void)extendBackgroundRunningTime {
if (_backgroundTask != UIBackgroundTaskInvalid) {
// if we are in here, that means the background task is already running.
// don't restart it.
return;
}
NSLog(@"Attempting to extend background running time");
__block Boolean self_terminate = YES;
_backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithName:@"DummyTask" expirationHandler:^{
NSLog(@"Background task expired by iOS");
if (self_terminate) {
[[UIApplication sharedApplication] endBackgroundTask:_backgroundTask];
_backgroundTask = UIBackgroundTaskInvalid;
}
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"Background task started");
while (true) {
NSLog(@"background time remaining: %8.2f", [UIApplication sharedApplication].backgroundTimeRemaining);
[NSThread sleepForTimeInterval:1];
}
});
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[self logString: [NSString stringWithFormat:@"applicationDidBecomeActive"]];
_inBackground = NO;
}
Getting 180 seconds to range in the background is no silver bullet, but it solves many use cases that 10 seconds does not.
You can read a full writeup on how this works, along with test results here: https://github.com/RadiusNetworks/ibeacon-background-demo/tree/background-task
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…