Deferredlocationupdatesavailable Returns No in iOS 10

deferredLocationUpdatesAvailable returns NO in iOS 10

Deferred updates are now officially deprecated (in iOS 13). This is effectively an admission that they have not been supported for several years.

How to get location updates power efficiently with ios when deferredlocationupdatesavailable returns NO

This answer might be a little off, because it is actually not possible anymore to use the deffering functionality even the doc has not been removed. But the intention was to switch on/off the location in intervals to avoid having it on all the time to conserve power.

To getting close to turning on/off completely, one might togge between high and low accuracy, this will save power for sure. (high accuracy typically <10m will use GPS module, low accuracy >500m will typically use AGPS.

First, start an NSTimer with the interval you want, then start updating with high accuracy. When receiving a location in didUpdateLocations, change from high accuracy to low accuracy. The callback of NSTimer requests a new high accuracy location update (ie calls setupHighAccuracy). The timer thus sets the frequency of the high accuracy updates. This will also work in the background because the location service is still running. If stopping updates, the app will stop in the background. When stopping and at once starting the location manager again, it will immediately call didUpdateLocation, but check the timestamp, the location may be buffered.

Showing some snippets below to get going. Production code will need more filtering and testing:

@property (retain, nonatomic) NSTimer *atimer;

static BOOL _lowAccuracy;

- (void)timerCallback {
[self setupHighAccuracy];
}

- (void)setupTimer
{
if(self.atimer != nil)
{
return;
}

UIApplication *app = [UIApplication sharedApplication];
__block UIBackgroundTaskIdentifier bgTaskId =
[app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTaskId];
bgTaskId = UIBackgroundTaskInvalid;
}];

dispatch_async( dispatch_get_main_queue(), ^{

self.atimer = [NSTimer scheduledTimerWithTimeInterval:15.0 // consider higher interval
target:self
selector:@selector(timerCallback)
userInfo:nil
repeats:YES];

}

[app endBackgroundTask:bgTaskId];
bgTaskId = UIBackgroundTaskInvalid;
});
}

- (void)setupHighAccuracy
{
if(_lowAccuracy)
{
[_locationManager performSelectorOnMainThread:@selector(stopUpdatingLocation) withObject:nil waitUntilDone:YES];
_locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters; // or kCLLocationAccuracyBest, tune yourself
_locationManager.activityType = CLActivityTypeFitness;
_locationManager.distanceFilter = 15; // or 0, tune yourself
_lowAccuracy = false;
[_locationManager performSelectorOnMainThread:@selector(startUpdatingLocation) withObject:nil waitUntilDone:YES];
}
}

- (void)setupLowAccuracy
{
if(!_lowAccuracy)
{
s_initialized = true;
[_locationManager performSelectorOnMainThread:@selector(stopUpdatingLocation) withObject:nil waitUntilDone:YES];
_locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
_locationManager.activityType = CLActivityTypeFitness;
_locationManager.distanceFilter = 3000;
_lowAccuracy = true;
[_locationManager performSelectorOnMainThread:@selector(startUpdatingLocation) withObject:nil waitUntilDone:YES];
}
}

- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations
{
CLLocation *location = locations.lastObject;
if(!_lowAccuracy) {
// update system with location here
[_locationManager.delegate setupLowAccuracy];
self.s_lastLocation = location;
}
}

iOS 11 deferredLocationUpdatesAvailable always return NO and Error Domain=kCLErrorDomain Code=11. How to make deferredlocationupdates work?

Unfortunatly, despite of all documentation and after weeks of frustrating development effort, I excepted the fact, that this functionality is not supported anymore. I tested it in all possible situations on 7 different real devices (iPads and iPhones, 5s up to 7) ... no success.

It did work perfectly on IOS 9, this is why I trust, that I know how to do it. But I tried every hint I found here and elsewere... no success under IOS 10 and 11.

If you look around you will find numerous angry comments from other coder. It‘s a shame, but we have to except the facts.

CLError.DeferredFailed Error (kCLErrorDomain Code=11) Deferred GPS Updates Failing

iOS 9.2, Xcode 7.2, ARC enabled

The problem is most likely associated with the distance and time interval you have chosen for your deferral. Try to take advantage of CLLocationDistanceMaxand CLTimeIntervalMax to troubleshoot the function call. For example, set the distance to CLLocationDistanceMax and then vary the time interval, then try vice versa.

But there are other things I see that you might want to change...

  1. Get rid of CLLocationManager.deferredLocationUpdatesAvailable() == true condition in the if statements to allow deferred location updates.
  2. Deferred updates were available iOS6.0+, most iPhone 4S can be updated to iOS7.2.1 depending on the hardware. You do not need to separately call _locationManager.startUpdatingLocation().
  3. Make sure that if you are testing in iOS9.0+ that you have the allowsBackgroundLocationUpdates set for the location manager.
  4. Make sure that the initial _locationManager.startUpdatingLocation() is made in the - (void)applicationWillResignActive:(UIApplication *)application method equivalent in Swift and NOT in the - (void)applicationDidEnterBackground:(UIApplication *)application method.
  5. Make sure that you are calling _locationManager.allowDeferredLocationUpdatesUntilTraveled(C_GPS.ACTIVITY_UPDATE_DISTANCE, timeout: C_GPS.ACTIVITY_UPDATE_TIME) in the equivalent of the - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations method for Swift.

Also, note that you are printing the error before you check if the error exists, this might lead to some incorrect error reporting.

Hope this helps and I am not too late! Cheers.

P.S. If this doesn't work, then please post more of your code, i.e. where you are calling these functions in relation to the app. delegate *.m file.



Related Topics



Leave a reply



Submit