在iOS上检查位置服务权限

我如何检查位置服务是否为我的应用程序启用?

我有2个故事板,我想检查位置服务。 如果为我的应用程序启用位置服务,我想启动地图情节串连位置。 否则,我想推出另一个故事板。 我怎样才能编程?

这是正确的。

if ([CLLocationManager locationServicesEnabled]){ NSLog(@"Location Services Enabled"); if ([CLLocationManager authorizationStatus]==kCLAuthorizationStatusDenied){ alert = [[UIAlertView alloc] initWithTitle:@"App Permission Denied" message:@"To re-enable, please go to Settings and turn on Location Service for this app." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; } } 

在iOS 9.2上testing

为了获取位置更新,我们应该经常检查

  • 在用户的iOS设备上启用位置服务
  • 为特定应用启用位置服务

并启动用户在正确的设置屏幕上启用

启动iOS设备位置设置页面

步骤1进入项目设置 – >信息 – > URLtypes – >添加新的URLscheme

在这里输入图像说明

步骤2使用以下代码启动直接电话的位置设置页面(注意:iOS 10+中的URLscheme不同,我们按照此处所述检查版本)

  #define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending) //Usage NSString* url = SYSTEM_VERSION_LESS_THAN(@"10.0") ? @"prefs:root=LOCATION_SERVICES" : @"App-Prefs:root=Privacy&path=LOCATION"; [[UIApplication sharedApplication] openURL:[NSURL URLWithString: url]]; 

在这里输入图像说明

启动应用程序位置设置页面

使用以下代码启动直接应用程序的位置设置页面

 [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]]; 

在这里输入图像说明

下面是完整的代码示例:#define SYSTEM_VERSION_LESS_THAN(v)([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)

 CLLocationManager *locationManager; -(void) checkLocationServicesAndStartUpdates { locationManager = [[CLLocationManager alloc] init]; locationManager.delegate = self; locationManager.desiredAccuracy = kCLLocationAccuracyBest; if ([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) { [locationManager requestWhenInUseAuthorization]; } //Checking authorization status if (![CLLocationManager locationServicesEnabled] && [CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied) { UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Location Services Disabled!" message:@"Please enable Location Based Services for better results! We promise to keep your location private" delegate:self cancelButtonTitle:@"Settings" otherButtonTitles:@"Cancel", nil]; //TODO if user has not given permission to device if (![CLLocationManager locationServicesEnabled]) { alertView.tag = 100; } //TODO if user has not given permission to particular app else { alertView.tag = 200; } [alertView show]; return; } else { //Location Services Enabled, let's start location updates [locationManager startUpdatingLocation]; } } 

处理用户点击响应,并启动正确的位置设置

 -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if(buttonIndex == 0)//Settings button pressed { if (alertView.tag == 100) { //This will open ios devices location settings NSString* url = SYSTEM_VERSION_LESS_THAN(@"10.0") ? @"prefs:root=LOCATION_SERVICES" : @"App-Prefs:root=Privacy&path=LOCATION"; [[UIApplication sharedApplication] openURL:[NSURL URLWithString: url]]; } else if (alertView.tag == 200) { //This will opne particular app location settings [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]]; } } else if(buttonIndex == 1)//Cancel button pressed. { //TODO for cancel } } 
 -(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{ NSLog(@"%@",error.userInfo); if([CLLocationManager locationServicesEnabled]){ NSLog(@"Location Services Enabled"); if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusDenied){ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"App Permission Denied" message:@"To re-enable, please go to Settings and turn on Location Service for this app." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; } } } 

在这个背后的原因,这个方法会调用你的服务时将会禁用位置服务。 这段代码对我很有用。

检查CLLocationManager的locationServicesEnabled属性以检查系统范围的可用性。 使用您的CLLocationManagerDelegate的locationManager:didFailWithError:方法,并检查kCLErrorDenied错误,以查看用户是否拒绝了位置服务。

 BOOL locationAllowed = [CLLocationManager locationServicesEnabled]; if (!locationAllowed) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Location Service Disabled" message:@"To re-enable, please go to Settings and turn on Location Service for this app." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; [alert release]; } 

为您的应用程序使用此代码

 - (void)viewDidLoad { locationManager = [[CLLocationManager alloc] init]; locationManager.delegate = self; locationManager.desiredAccuracy = kCLLocationAccuracyKilometer; // Set a movement threshold for new events. locationManager.distanceFilter = 500; [locationManager startUpdatingLocation]; [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { // If it's a relatively recent event, turn off updates to save power } - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { NSLog(@"%@",error); } 

如果位置服务禁用您的应用程序然后它给你错误

 Error Domain=kCLErrorDomain Code=1 "The operation couldn't be completed. (kCLErrorDomain error 1.)" 

经过很多调查。 我会build议在标签上显示此消息,而不是在警报视图中显示。 因为有很多情况下需要testing(用户通常禁用位置服务,或者只是为了删除应用程序,重新安装)。

其中一种情况会导致您的警报同时显示您的消息以及苹果的警报消息。 你的警报将落后于苹果的警惕。 这是一个混乱和不合逻辑的行为。

我build议如下:

Swift 3:

 func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { switch status { case .notDetermined: Log.verbose("User still thinking granting location access!") manager.startUpdatingLocation() // this will access location automatically if user granted access manually. and will not show apple's request alert twice. (Tested) break case .denied: Log.verbose("User denied location access request!!") // show text on label label.text = "To re-enable, please go to Settings and turn on Location Service for this app." manager.stopUpdatingLocation() loadingView.stopLoading() break case .authorizedWhenInUse: // clear text label.text = "" manager.startUpdatingLocation() //Will update location immediately break case .authorizedAlways: // clear text label.text = "" manager.startUpdatingLocation() //Will update location immediately break default: break } } 

Objective-C的:

 - (void)locationManager:(CLLocationManager*)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { switch (status) { case kCLAuthorizationStatusNotDetermined: { DDLogVerbose(@"User still thinking granting location access!"); [locationManager startUpdatingLocation]; // this will access location automatically if user granted access manually. and will not show apple's request alert twice. (Tested) } break; case kCLAuthorizationStatusDenied: { DDLogVerbose(@"User denied location access request!!"); // show text on label label.text = @"To re-enable, please go to Settings and turn on Location Service for this app."; [locationManager stopUpdatingLocation]; [loadingView stopLoading]; } break; case kCLAuthorizationStatusAuthorizedWhenInUse: case kCLAuthorizationStatusAuthorizedAlways: { // clear text label.text = @""; [locationManager startUpdatingLocation]; //Will update location immediately } break; default: break; } } 

Swift 3.0和iOS 10解决scheme:


 self.locationManager?.requestWhenInUseAuthorization() if CLLocationManager.locationServicesEnabled() && CLLocationManager.authorizationStatus() != CLAuthorizationStatus.denied { locationManager?.delegate = self locationManager?.desiredAccuracy = kCLLocationAccuracyBestForNavigation locationManager?.distanceFilter = distanceFiler locationManager?.startUpdatingLocation() }else{ let alertView = UIAlertView(title: "Location Services Disabled!", message: "Please enable Location Based Services for better results! We promise to keep your location private", delegate: self, cancelButtonTitle: "Settings", otherButtonTitles: "Cancel") alertView.delegate = self alertView.show() return } @objc(alertView:clickedButtonAtIndex:) func alertView(_ alertView: UIAlertView, clickedButtonAt buttonIndex: Int) { if buttonIndex == 0 { if let url = URL(string: "App-Prefs:root=LOCATION_SERVICES") { UIApplication.shared.open(url, completionHandler: .none) } } else if buttonIndex == 1 { //TODO for cancel } } 

最好的办法,处理所有案件! – >

 //First, checking if the location services are enabled if(![CLLocationManager locationServicesEnabled]){ [self showMessage:@"Please enable location services to detect location!" withTitle:@"Location not enabled"]; } else if ([CLLocationManager authorizationStatus]==kCLAuthorizationStatusDenied){ //Now if the location is denied. UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Enable location permission" message:@"To auto detect location, please enable location services for this app" preferredStyle:UIAlertControllerStyleAlert]; alertController.view.tintColor = AppColor; UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Dismiss" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { NSLog(@"Cancel action"); }]; UIAlertAction *goToSettings = [UIAlertAction actionWithTitle:@"Settings" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { //Simple way to open settings module NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; [[UIApplication sharedApplication] openURL:url]; }]; [alertController addAction:cancelAction]; [alertController addAction:goToSettings]; [self presentViewController:alertController animated:YES completion:^{ alertController.view.tintColor = AppColor; }]; } else{ //Do whatever you want here }