我正在尝试在我的iOS应用中获取用户位置.我首先在我的项目中包含了重置框架.然后在按钮上单击我调用核心位置api,如下所示.当我尝试在设备中安装它时,核心位置永远不会询问用户权限.当我尝试在按钮单击时获取位置时,我将获得kCLAuthorizationStatusNotDetermined作为authorisationStatus.请帮帮我.我不知道发生了什么.
- (IBAction)fetchLessAccurateLocation:(id)sender { [self.txtLocation setText:@""]; locationManager = [[CLLocationManager alloc] init]; locationManager.delegate = self; locationManager.desiredAccuracy = kCLLocationAccuracyKilometer; locationManager.distanceFilter = 1000; if ([self shouldFetchUserLocation]) { [locationManager startUpdatingLocation]; } }
这是我的shouldFetchUserLocation方法:
-(BOOL)shouldFetchUserLocation{ BOOL shouldFetchLocation= NO; if ([CLLocationManager locationServicesEnabled]) { switch ([CLLocationManager authorizationStatus]) { case kCLAuthorizationStatusAuthorized: shouldFetchLocation= YES; break; case kCLAuthorizationStatusDenied: { UIAlertView *alert= [[UIAlertView alloc]initWithTitle:@"Error" message:@"App level settings has been denied" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil]; [alert show]; alert= nil; } break; case kCLAuthorizationStatusNotDetermined: { UIAlertView *alert= [[UIAlertView alloc]initWithTitle:@"Error" message:@"The user is yet to provide the permission" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil]; [alert show]; alert= nil; } break; case kCLAuthorizationStatusRestricted: { UIAlertView *alert= [[UIAlertView alloc]initWithTitle:@"Error" message:@"The app is recstricted from using location services." delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil]; [alert show]; alert= nil; } break; default: break; } } else{ UIAlertView *alert= [[UIAlertView alloc]initWithTitle:@"Error" message:@"The location services seems to be disabled from the settings." delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil]; [alert show]; alert= nil; } return shouldFetchLocation; }
这是我的核心位置委托方法:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_6_0){ NSLog(@"location fetched in delegate"); CLLocation* location = [locations lastObject]; NSDate* eventDate = location.timestamp; NSTimeInterval howRecent = [eventDate timeIntervalSinceNow]; if (abs(howRecent) < 15.0) { // If the event is recent, do something with it. NSLog(@"inside loop.... latitude %+.6f, longitude %+.6f\n", location.coordinate.latitude, location.coordinate.longitude); } NSLog(@"latitude %+.6f, longitude %+.6f\n", location.coordinate.latitude, location.coordinate.longitude); [self.txtLocation setText:[NSString stringWithFormat:@"\nlatitude: %+.6f \nlongitude: %+.6f", location.coordinate.latitude, location.coordinate.longitude]]; [locationManager stopUpdatingLocation]; [locationManager stopMonitoringSignificantLocationChanges]; if(locationManager!=nil){ locationManager.delegate= nil; locationManager= nil; } }
小智.. 101
假设
[CLLocationManager locationServicesEnabled]
返回YES,
首次启动iOS应用程序[iOS7和iOS8] - locationMangers(CLLocationManager)authorizationStatus预设为
authorizationStatus(CLAuthorizationStatus) = kCLAuthorizationStatusNotDetermined
启动locationManger(CLLocationManager,Strong)并设置委托(CLLocationManagerDelegate)
现在提示用户使用位置服务并列出应用程序>隐私>位置服务下的应用程序,它必须调用任何位置服务方法,它取决于应用程序要求 - 例如,如果应用程序是以下类型之一
地点更新 - [self.locationManager startUpdatingLocation]
RegionMonitoring - [self.locationManager startMonitoringForRegion:beaconRegion]
在执行上述方法后,iOS将提示用户请求在应用程序中接受使用位置服务,无论用户选择应用程序将在"设置">"隐私">"位置服务"下列出.
与iOS8相同,第一次启动App Locations Services
authorizationStatus(CLAuthorizationStatus) = kCLAuthorizationStatusNotDetermined
iOS 8我们获得了向用户显示提示的新方法
[self.locationManager requestAlwaysAuthorization] or [self.locationManager requestWhenInUseAuthorization]
requestAlwaysAuthorization/requestWhenInUseAuthorization可以从iOS8获得.如果App部署目标是iOS7,那么将其包装在if块下以确保在iOS7中这不会导致应用程序崩溃.
if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) { [self.locationManager requestAlwaysAuthorization]; . }
要么
if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) { [self.locationManager requestWhenInUseAuthorization]; }
根据iOS8,它必须包含说明为什么app使用requestAlwaysAuthorization/requestWhenInUseAuthorization的字符串在info.plist中包含与app的要求相对应的任何属性
for kCLAuthorizationStatusAuthorizedAlways包括Key/Value(字符串值)对
NSLocationAlwaysUsageDescription = App use Locations service mode Always
for kCLAuthorizationStatusAuthorizedWhenInUse包含Key/Value(字符串值)对
NSLocationWhenInUseUsageDescription = App use Locations service mode In Use
info.plist的屏幕截图(如果有人对此感到困惑)
Objective-C 遵循以下说明:
iOS-11 对于iOS 11,请查看此答案:iOS 11位置访问
需要在plist中添加两个密钥并提供如下图所示的消息:
1. NSLocationAlwaysAndWhenInUseUsageDescription 2. NSLocationWhenInUseUsageDescription
iOS-10及以下版本:
NSLocationWhenInUseUsageDescription
locationManager = [[CLLocationManager alloc] init]; locationManager.delegate = self; locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers; if([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]){ [locationManager requestWhenInUseAuthorization]; }else{ [locationManager startUpdatingLocation]; }
代表方法
#pragma mark - Lolcation Update - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { NSLog(@"didFailWithError: %@", error); UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [errorAlert show]; } -(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { switch (status) { case kCLAuthorizationStatusNotDetermined: case kCLAuthorizationStatusRestricted: case kCLAuthorizationStatusDenied: { // do some error handling } break; default:{ [locationManager startUpdatingLocation]; } break; } } - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { CLLocation *location = [locations lastObject]; userLatitude = [NSString stringWithFormat:@"%f", location.coordinate.latitude] ; userLongitude = [NSString stringWithFormat:@"%f",location.coordinate.longitude]; [locationManager stopUpdatingLocation]; }
SWIFT代码
请按照以下说明操作:
iOS-11 对于iOS 11,请查看此答案:iOS 11位置访问
需要在plist中添加两个密钥并提供如下图所示的消息:
1. NSLocationAlwaysAndWhenInUseUsageDescription 2. NSLocationWhenInUseUsageDescription
iOS-10及以下版本:
import CoreLocation class ViewController: UIViewController ,CLLocationManagerDelegate { var locationManager = CLLocationManager() //MARK- Update Location func updateMyLocation(){ locationManager.delegate = self; locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers; if locationManager.respondsToSelector(#selector(CLLocationManager.requestWhenInUseAuthorization)){ locationManager.requestWhenInUseAuthorization() } else{ locationManager.startUpdatingLocation() } }
代表方法
//MARK: Location Update func locationManager(manager: CLLocationManager, didFailWithError error: NSError) { NSLog("Error to update location :%@",error) } func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) { switch status { case .NotDetermined: break case .Restricted: break case .Denied: NSLog("do some error handling") break default: locationManager.startUpdatingLocation() } } func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { let location = locations.last! as CLLocation var latitude = location.coordinate.latitude var longitude = location.coordinate.longitude }
我遇到了同样的问题,在重新安装我的应用程序之后,kCLAuthorizationStatusNotDetermined
每当检查时它都会返回,[CLLocationManager authorizationStatus]
并且应用程序甚至没有显示在"设置">"隐私">"位置服务"中.
将触发iOS提示用户批准访问位置服务的授权对话框,在[locationManager startUpdatingLocation]
此情况下永远不会调用(shouldFetchUserLocation
将始终NO
).
米格尔C.的解决方案似乎是一个很好的解决方案,将尝试.
当iOS8出现时,它对CLLocationManager的使用方式几乎没有任何改变.正如在其他答案中提到的那样,与iOS7相比,它需要额外的步骤.今天我自己遇到了这个问题并找到了这篇文章(它已经从多个其他问题中引用,但它完成了我之前的回答).希望能帮助到你!
假设
[CLLocationManager locationServicesEnabled]
返回YES,
首次启动iOS应用程序[iOS7和iOS8] - locationMangers(CLLocationManager)authorizationStatus预设为
authorizationStatus(CLAuthorizationStatus) = kCLAuthorizationStatusNotDetermined
启动locationManger(CLLocationManager,Strong)并设置委托(CLLocationManagerDelegate)
现在提示用户使用位置服务并列出应用程序>隐私>位置服务下的应用程序,它必须调用任何位置服务方法,它取决于应用程序要求 - 例如,如果应用程序是以下类型之一
地点更新 - [self.locationManager startUpdatingLocation]
RegionMonitoring - [self.locationManager startMonitoringForRegion:beaconRegion]
在执行上述方法后,iOS将提示用户请求在应用程序中接受使用位置服务,无论用户选择应用程序将在"设置">"隐私">"位置服务"下列出.
与iOS8相同,第一次启动App Locations Services
authorizationStatus(CLAuthorizationStatus) = kCLAuthorizationStatusNotDetermined
iOS 8我们获得了向用户显示提示的新方法
[self.locationManager requestAlwaysAuthorization] or [self.locationManager requestWhenInUseAuthorization]
requestAlwaysAuthorization/requestWhenInUseAuthorization可以从iOS8获得.如果App部署目标是iOS7,那么将其包装在if块下以确保在iOS7中这不会导致应用程序崩溃.
if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) { [self.locationManager requestAlwaysAuthorization]; . }
要么
if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) { [self.locationManager requestWhenInUseAuthorization]; }
根据iOS8,它必须包含说明为什么app使用requestAlwaysAuthorization/requestWhenInUseAuthorization的字符串在info.plist中包含与app的要求相对应的任何属性
for kCLAuthorizationStatusAuthorizedAlways包括Key/Value(字符串值)对
NSLocationAlwaysUsageDescription = App use Locations service mode Always
for kCLAuthorizationStatusAuthorizedWhenInUse包含Key/Value(字符串值)对
NSLocationWhenInUseUsageDescription = App use Locations service mode In Use
info.plist的屏幕截图(如果有人对此感到困惑)
你一定是NSLocationWhenInUseUsageDescription
加了你的info.plist
.它有点奇怪,但只是添加为没有文本的字符串值,然后当你想要位置开始时:
CLLocationManager * locationManager = [[CLLocationManager alloc] init]; [locationManager requestWhenInUseAuthorization];
在iOS 8中,您需要做两件额外的事情才能使位置正常工作:在Info.plist中添加一个密钥,并向位置管理员请求授权以启动它.新位置授权有两个Info.plist键.需要这些键中的一个或两个.如果两个键都不存在,则可以调用startUpdatingLocation,但位置管理器实际上不会启动.它也不会向委托发送失败消息(因为它从未启动过,它不会失败).如果您添加一个或两个密钥但忘记明确请求授权,它也将失败.
因此,您需要做的第一件事是将以下一个或两个密钥添加到Info.plist文件中:
NSLocationWhenInUseUsageDescription NSLocationAlwaysUsageDescription
这两个键都带有一个字符串,它描述了您需要位置服务的原因.您可以输入一个字符串,如"需要位置以查找您所在的位置",如iOS 7中所示,可以在InfoPlist.strings文件中进行本地化.
接下来,您需要请求相应位置方法,WhenInUse或Background的授权.使用以下电话之一:
[self.locationManager requestWhenInUseAuthorization] [self.locationManager requestAlwaysAuthorization]
有关更多信息.
如果您在iOS8上遇到此问题,请使用:requestWhenInUseAuthorization.