简体   繁体   中英

didUpdateLocations keeps calling every second with deferred updates

I'm trying to implement the deferred location updates to have a better battery consumption. I'm starting my location manager like this :

- (void)initCoreLocation
{
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    self.locationManager.distanceFilter = kCLDistanceFilterNone;
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    self.locationManager.pausesLocationUpdatesAutomatically = YES;
    self.locationManager.activityType = CLActivityTypeAutomotiveNavigation;

    //Très important pour iOS9 !
    if ([self.locationManager respondsToSelector:@selector(allowsBackgroundLocationUpdates)]) {
        self.locationManager.allowsBackgroundLocationUpdates=YES;
    }

    if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
        [self.locationManager requestAlwaysAuthorization];
    }

    [self.locationManager startUpdatingLocation];
    [self.locationManager startMonitoringSignificantLocationChanges];
}

And starting deferred update like this way:

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{

    if (!self.deferringUpdates) {
        [self.locationManager allowDeferredLocationUpdatesUntilTraveled:CLLocationDistanceMax timeout:30];
        self.deferringUpdates = YES;
    }
}

-(void)locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error { // Stop deferring updates
    if(error) {
        NSLog(@"error");
    }
    NSLog(@"didFinishDeferredUpdates");
    self.deferringUpdates = NO;
}

I have didFinishDeferredUpdates log every 30 seconds, however didUpdateLocations keeps calling every second, removing any try to optimise the battery consumption. Is it supposing to the location manager to call the didUpdateLocations every 30 seconds ?

Maybe you are not having the right approach as allowDeferredLocationUpdatesUntilTraveled() tells the GPS hardware to store new locations internally until the specified distance or timeout conditions are met.

From the iOS Developer Library:

If your app is in the foreground, the location manager does not defer the deliver of events but does monitor for the specified criteria. If your app moves to the background before the criteria are met, the location manager may begin deferring the delivery of events. Link

Are you debugging?

As stated in the answer here: ios deferred location updates fail to defer

Deferred updates are delivered only when the system enters a low power state. Deferred updates do not occur during debugging because Xcode prevents your app from sleeping and thus prevents the system from entering that low power state.

I believe you only need one of them at one time, change the call in applicationDidEnterBackground and applicationWillEnterForeground

- (**void)applicationDidEnterBackground:(UIApplication *)application {

    // Need to stop regular updates first
    [self.locationManager stopUpdatingLocation];
    // Only monitor significant changes
    [self.locationManager startMonitoringSignificantLocationChanges];
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    [self.locationManager stopMonitoringSignificantLocationChanges];
    [self.locationManager startUpdatingLocation];
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM