Xcode 使用 MapKit 和 CoreLocation 时出现警告
Xcode warning when using MapKit and CoreLocation
我正在尝试使用 MKMapView
的实例,使用 CoreLocation
来跟踪用户位置,然后放大他们所在的位置。
我只想在前台时跟踪用户的位置。由于我的应用程序针对 iOS8,因此我有一个密钥 NSLocationWhenInUseUsageDescription
的 plist 条目。
当我第一次 运行 该应用程序时,该应用程序会适当地询问它是否可以访问我的位置。单击 'Allow' 后,我收到来自 Xcode 的以下警告:
Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.
...这有点令人困惑,因为我实际上是在调用 requestWhenInUseAuthorization
,如下面的代码所示:
@property (strong, nonatomic) IBOutlet MKMapView *mapView;
@property(nonatomic, retain) CLLocationManager *locationManager;
@end
@implementation MapView
- (void)viewDidLoad {
[super viewDidLoad];
[self locationManager];
[self updateLocation];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
self.locationManager = nil;
}
- (CLLocationManager *)locationManager {
//We only want to get the location when the app is in the foreground
[_locationManager requestWhenInUseAuthorization];
if (!_locationManager) {
_locationManager = [[CLLocationManager alloc] init];
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
}
return _locationManager;
}
- (void)updateLocation {
_mapView.userTrackingMode = YES;
[self.locationManager startUpdatingLocation];
}
有没有人知道为什么会出现此警告?
您正在呼叫 requestWhenInUseAuthorization
,是的。但是您是否在等到 获得 授权?不,你不是。您(作为用户)正在点击“允许”,但为时已晚:您的代码 已经 继续,直接告诉地图视图开始跟踪用户的位置。
只需查看 requestWhenInUseAuthorization
上的文档即可:
When the current authorization status is kCLAuthorizationStatusNotDetermined, this method runs asynchronously
明白了吗? 异步运行。这意味着请求权限发生在另一个线程的后台。
文档接着说:
After the status is determined, the location manager delivers the results to the delegate’s locationManager:didChangeAuthorizationStatus:
method
所以,实现那个方法。如果您刚刚获得许可,那就是您可以开始使用位置管理器的信号。
此外,您错过了一个重要的步骤:您没有检查实际是什么状态。如果状态未确定,您应该只请求授权。如果状态被限制或拒绝,则您根本不能使用位置管理器;如果状态被授予,则无需再次请求授权。
所以,总结一下,你的逻辑流程图应该是:
检查状态。
状态是Restricted还是Denied?停止。您不能使用获取位置更新或在地图上定位。
状态是Granted吗?继续获取位置更新或在地图上定位。
状态是否未确定?请求授权并停止。将 locationManager:didChangeAuthorizationStatus:
视为授权请求的完成处理程序。在那一点上,回到流程图的开始!
我正在尝试使用 MKMapView
的实例,使用 CoreLocation
来跟踪用户位置,然后放大他们所在的位置。
我只想在前台时跟踪用户的位置。由于我的应用程序针对 iOS8,因此我有一个密钥 NSLocationWhenInUseUsageDescription
的 plist 条目。
当我第一次 运行 该应用程序时,该应用程序会适当地询问它是否可以访问我的位置。单击 'Allow' 后,我收到来自 Xcode 的以下警告:
Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.
...这有点令人困惑,因为我实际上是在调用 requestWhenInUseAuthorization
,如下面的代码所示:
@property (strong, nonatomic) IBOutlet MKMapView *mapView;
@property(nonatomic, retain) CLLocationManager *locationManager;
@end
@implementation MapView
- (void)viewDidLoad {
[super viewDidLoad];
[self locationManager];
[self updateLocation];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
self.locationManager = nil;
}
- (CLLocationManager *)locationManager {
//We only want to get the location when the app is in the foreground
[_locationManager requestWhenInUseAuthorization];
if (!_locationManager) {
_locationManager = [[CLLocationManager alloc] init];
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
}
return _locationManager;
}
- (void)updateLocation {
_mapView.userTrackingMode = YES;
[self.locationManager startUpdatingLocation];
}
有没有人知道为什么会出现此警告?
您正在呼叫 requestWhenInUseAuthorization
,是的。但是您是否在等到 获得 授权?不,你不是。您(作为用户)正在点击“允许”,但为时已晚:您的代码 已经 继续,直接告诉地图视图开始跟踪用户的位置。
只需查看 requestWhenInUseAuthorization
上的文档即可:
When the current authorization status is kCLAuthorizationStatusNotDetermined, this method runs asynchronously
明白了吗? 异步运行。这意味着请求权限发生在另一个线程的后台。
文档接着说:
After the status is determined, the location manager delivers the results to the delegate’s
locationManager:didChangeAuthorizationStatus:
method
所以,实现那个方法。如果您刚刚获得许可,那就是您可以开始使用位置管理器的信号。
此外,您错过了一个重要的步骤:您没有检查实际是什么状态。如果状态未确定,您应该只请求授权。如果状态被限制或拒绝,则您根本不能使用位置管理器;如果状态被授予,则无需再次请求授权。
所以,总结一下,你的逻辑流程图应该是:
检查状态。
状态是Restricted还是Denied?停止。您不能使用获取位置更新或在地图上定位。
状态是Granted吗?继续获取位置更新或在地图上定位。
状态是否未确定?请求授权并停止。将
locationManager:didChangeAuthorizationStatus:
视为授权请求的完成处理程序。在那一点上,回到流程图的开始!