0

I wrote a CLLocationManager Singleton called LocationManager and want to observe updated location. But the observing part is not working. Can anyone tell me what the problem is. Thanks. The following are my codes:

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if(object == self){
    if([keyPath isEqualToString:@"curStandardLocation"]){
        NSLog(@"current location is changed ....");
    }
}}(in LocationManager.m)

if([self.locationManager locationmanagerstatus]){
    [self.locationManager startLocationTracking];
    [[LocationManager sharedInstance] addObserver:self forKeyPath:@"curStandardLocation" options:NSKeyValueObservingOptionNew context:nil];} (in a separate viewcontroller where I need to listen to the location)
Jennifer He
  • 75
  • 1
  • 2
  • 10
  • 2
    It doesn't look -- from the way you describe it -- as if `observeValueForKeyPath` is in the same object that adds itself as an observer. – Phillip Mills Oct 28 '15 at 17:18
  • +1 for Phillip's comment, plus: You should always use a unique context when adding a key-value observer. You should always check the context in `-observeValueForKeyPath:...` and call through to super if it doesn't match yours. The `object` parameter in `-observeValueForKeyPath:...` is the observed object, the one whose property is changing. It would not typically be `self`. In your case, it would be `[LocationManager sharedInstance]`. Finally, you need to take care to make sure that your `LocationManager` class is KVO-compliant for its `curStandardLocation` property. – Ken Thomases Oct 28 '15 at 18:04
  • @PhillipMills Thank you for your help. Could you elaborate your answer? I did not understand. :( – Jennifer He Oct 28 '15 at 20:25
  • @KenThomases Thanks very much for your help. what kind of constraints should i give to curStandardLocation property? – Jennifer He Oct 28 '15 at 20:27
  • You need to only manipulate it in ways that generate KVO change notifications. That mostly means you must always set it through its setter, never assign directly to the instance variable. See [here](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/KeyValueObserving/Articles/KVOCompliance.html). – Ken Thomases Oct 28 '15 at 21:11

1 Answers1

0

If you want to track location changes you can do that with

Instantiate the manager in our controller's init method:

_locationManager = [[CLLocationManager alloc] init];
[_locationManager setDelegate:self];
[_locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[locationManager startUpdatingLocation];
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8) {
        [locationManager requestWhenInUseAuthorization];
    }

In the viewWillAppear: method, start monitoring signification location changes.

if ([CLLocationManager locationServicesEnabled]) {
    // Find the current location
    [self.locationManager startMonitoringSignificantLocationChanges];
    //rest of code...
}

Significant change monitoring is good because:

  • It has lower power consumption than more frequent update types.
  • "Significant" changes are variable but way less than the few miles used to trigger the push.
  • The delegate will be called even if the app is in the background, allow using to continuously update the user's location, even when not using the app.

Here are the two important callbacks to implement, locationManager:didUpdateLocations: and locationManager:didFailWithError:

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    // locations contains an array of recent locations, but this app only cares about the most recent
    // which is also "manager.location"
}

Also add in your info.plist

 <key>NSLocationUsageDescription</key>
 <string>The application require location services to work</string>
 <key>NSLocationAlwaysUsageDescription</key>
 <string>The application require location services to work</string>
 <key>NSLocationWhenInUseUsageDescription</key>
 <string>The application require location services to work</string>
Piyush Sharma
  • 1,891
  • 16
  • 23