Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
462 views
in Technique[技术] by (71.8m points)

background - Will iOS wake up the terminated app if it's registered with location for UIBackgroundModes?

I know that if an app uses "The significant-change location service", iOS will wake it up if there's a location update to be delivered, even if the app is terminated.

I couldn't find a clear answer about the case if the app is using standard location services and specifies location as the key for UIBackgroundModes: Will iOS also wake it up to deliver the update even if it's terminated? Or does the app need to be running in the background to get the location update callback?

UPDATE: At the time I was asking this, I didn't have the time to test it. But after I got an answer here, I wrote this piece of code in my application's delegate to see if my terminated app will be relaunched when it gets a location update. I'm displaying a UILocalNotification when I'm notified of the update. However, when I terminated my app and then changed my location in the city, the app was not relaunched and I didn't get any updates. Can you tell me what it's that I'm doing wrong?

UPDATE #2: According to the final findings in this Q&A, there's nothing wrong with this code and it's the expected behaviour for an app that uses standard location services, not to be relaunched after termination.

I've added location as one of the UIBackgroundModes in the Info.plist file.

And this is the location related parts of my app delegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    [UIApplication sharedApplication].applicationIconBadgeNumber = 0;

    m_locManager = [[CLLocationManager alloc] init];
    m_locManager.delegate = self;
    [m_locManager startUpdatingLocation];
    return YES;
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    [m_locManager startUpdatingLocation];
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog("%@", [NSString stringWithFormat:@"Background Fail %@", [error localizedDescription]]);
}

- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation
{
    UILocalNotification * theNotification = [[UILocalNotification alloc] init];
    theNotification.alertBody = [NSString stringWithFormat:@"Background location %.06f %.06f %@" , newLocation.coordinate.latitude, newLocation.coordinate.longitude, newLocation.timestamp];
    theNotification.alertAction = @"Ok";

    theNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:1];

    [[UIApplication sharedApplication] scheduleLocalNotification:theNotification];
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Looks like you found a workable solution and it seems like using the significant change framework would save you some battery life, so long as it is accurate enough for your purposes. Your solution is also beneficial because it allows you to juggle potentially more than the per-app limit of 20 regions allowed to be simultaneously monitored, by only monitoring those regions that you are closest to.

I need similar functionality, but don't think the significant change would be accurate enough for my app, so I dug around some more and found the following.

Per the Location Awareness Programming Guide, under "Monitoring Shape-Based Regions":

In iOS, regions associated with your app are tracked at all times, including when your app is not running. If a region boundary is crossed while an app is not running, that app is relaunched into the background to handle the event. Similarly, if the app is suspended when the event occurs, it is woken up and given a short amount of time to handle the event.

And also in "Handling Boundary-Crossing Events for a Region":

Every time the user’s current location crosses a boundary region, the system generates an appropriate region event for your app. If your app is already running, these events go directly to the delegates of any current location manager objects. If your app is not running, the system launches it in the background so that it can respond. Apps can implement the following methods to handle boundary crossings:

locationManager:didEnterRegion:

locationManager:didExitRegion:

In my case, I just needed to fire a notification when the boundary was crossed, so I set my AppDelegate to conform to CLLocationManagerDelegate, created a locationManager property, and put this in my implementation file:

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.locationManager.delegate = self;
    return YES;
}

- (CLLocationManager *)locationManager
{
    if (!_locationManager) {
        _locationManager = [[CLLocationManager alloc] init];
        _locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
    }
    return _locationManager;
}

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    UILocalNotification *notification = [[UILocalNotification alloc] init];
    notification.alertBody = NSLocalizedString(@"You crossed a boundary!", @"user crossed a boundary");
    [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}

Testing shows this works without the UIBackgroundModes location key needing to be set. In this use-case, the OS handles boundary monitoring for you and then sends the event to your app just long enough to process the event. This doesn't launch the app, it just runs it in the background for a few seconds to process the boundary event, during which time you can only do relevant activities. Hope this helps someone else, too!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...