2

I have been trying to implement deferred location updates in an app for the past two days. The problem I am facing is that

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

method is being called each second even after I call the

 [self.locMgr allowDeferredLocationUpdatesUntilTraveled:(CLLocationDistance)200 timeout:(NSTimeInterval)25];

method.

ALthough I have to say that

 - (void)locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error

is called exactly after 25 seconds as specified by me allowDeferredLocationUpdatesUntilTraveled method with error code = null.

It is my understanding from the docs that didUpdateLocations should be called after 25 seconds only. Any help would be much appreciated.

David Rönnqvist
  • 56,267
  • 18
  • 167
  • 205
Alejandro Vargas
  • 1,327
  • 12
  • 26
  • I checked almost all the forums present on deferring in ios and found this. It has almost the same issue that i am facing. https://devforums.apple.com/message/903992#903992 – Alejandro Vargas Dec 04 '13 at 12:44
  • I dont think I will get a correct answer.The following link seemed helpful, https://devforums.apple.com/message/766429#766429 Posting it cause it may be helpful to others. – Alejandro Vargas Dec 04 '13 at 13:42

2 Answers2

5

I have been struggling with the same issue, and I may have found an answer that solves this problem for many - at least it solves my problem and gets deferred updates working consistently for me. I followed all of the steps in the list above and no matter what I did, location updates would not defer. It occurred to me that I might have other apps running that were not allowing the system to sleep, so I killed all other apps in the multitasking tray. I ran my sample app again and ... it worked! But the story doesn't end there. I tried again a little later, and even though there were no other apps running in the multitasking tray I couldn't get location services to defer. Then it occurred to me that I have an app on my phone called "Moves" which manages to keep itself alive even after you manually kill it. I'm not entirely sure how Moves comes magically back to life when you kill it, but it does (perhaps using bluetooth and the app preservation / restoration service). Even though it is alive and tracking your location it doesn't appear in the multitasking tray. I think that only apps that are manually launched appear in the tray - if the OS launches an app it doesn't appear in the tray. But I digress ... I was able to get deferred location services to work consistently in my app by disallowing Moves to use location services. When I did, Moves complained even though it wasn't in multitasking tray. It seems that if another app is using location services (and not deferring) your app won't defer either.

Colin Phillips
  • 1,001
  • 1
  • 10
  • 11
4

According to the Apple Developer Forums for the iOS 6.0 SDK, deferred location updates are only available:

  • on iPhone 5 hardware
  • running iOS 6.0 or higher
  • desired accuracy set to kCLLocationAccuracyBest
  • call the "startUpdatingLocation" method
  • wait for location updates to come in at approximately 1 per second
  • then begin deferring updates

See: https://devforums.apple.com/message/751974#751974

So sounds like you need iPhone 5 hardware, and to wait for location updates to come in at 1Hz.

Toseef Khilji
  • 17,192
  • 12
  • 80
  • 121
  • And yes I forgot to mention, I am using an actual iphone 5 , tested with both ios 6 and 7 versions, had a clear view of the sky and also have taken care of all the points mentioned by @viruss mca I beleive u took this answer from http://stackoverflow.com/questions/12992380/how-to-work-with-deferred-location-ios-6 – Alejandro Vargas Dec 04 '13 at 12:40
  • @giddyboy: of course it is from it.can you show initialisation of location manager? – Toseef Khilji Dec 04 '13 at 12:46
  • - (id)init { self = [super init]; if(self != nil) { if([CLLocationManager locationServicesEnabled]) { self.locMgr = [[CLLocationManager alloc] init]; self.locMgr.delegate = self; self.locMgr.desiredAccuracy = kCLLocationAccuracyBest; [self.locMgr setDistanceFilter: kCLDistanceFilterNone]; } else { self.locMgr = nil; } } return self; } Is this it? – Alejandro Vargas Dec 04 '13 at 12:53
  • try removing after `[self.locMgr setDistanceFilter: kCLDistanceFilterNone];`. – Toseef Khilji Dec 04 '13 at 12:55
  • I tried with that. The location manager reports an error with error code 12( a kCLErrorDeferredDistanceFiltered error). Also it is written in the docs that we have to set it to kCLDistanceFilterNone. – Alejandro Vargas Dec 04 '13 at 13:01