首先为观察者设置一个静态上下文(将它放在你的@implementation 上方),我们将使用它的地址(&)为我们提供这个类的唯一上下文:
static NSString* kShowsUserLocationChanged = @"kShowsUserLocationChanged";
接下来,您需要观察 MKMapView 的 showsUserLocation 属性:
[self.mapView addObserver:self
forKeyPath:@"showsUserLocation"
options:(NSKeyValueObservingOptionNew |
NSKeyValueObservingOptionOld)
context:&kShowsUserLocationChanged];
如果之前没有确定,那么你需要一个请求授权的方法,作为奖励,我的方法还检查 Info.plist 是否配置正确,如果不是这样,就会提醒开发人员:
-(void)_requestLocationAuthorizationIfNotDetermined{
if([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined){
BOOL always = NO;
if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"]){
always = YES;
}
else if(![[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]){
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Location usage description missing from Info.plist" userInfo:nil];
}
static CLLocationManager* lm = nil;
static dispatch_once_t once;
dispatch_once(&once, ^ {
// Code to run once
lm = [[CLLocationManager alloc] init];
});
if(always){
[lm requestAlwaysAuthorization];
}else{
[lm requestWhenInUseAuthorization];
}
}
}
最后,需要添加observe方法实现:
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
// if it was our observation
if(context == &kShowsUserLocationChanged){
// if its being enabled
if([[change objectForKey:NSKeyValueChangeNewKey] boolValue]){
[self _requestLocationAuthorizationIfNotDetermined];
}
}
else{
// if necessary, pass the method up the subclass hierarchy.
if([super respondsToSelector:@selector(observeValueForKeyPath:ofObject:change:context:)]){
[super observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context];
}
}
}
您可以通过卸载应用程序来测试它,这会清除下一次部署和运行的授权状态。