iOS:应用程序在安装应用程序时不会询问用户的权限.每次都得到kCLAuthorizationStatusNotDetermined - Objective-c&Swift

 伊夕言 发布于 2023-02-09 13:35

我正在尝试在我的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

iOS8通过LocationsServices为我们带来了主要的API更改

假设 [CLLocationManager locationServicesEnabled]返回YES,

首次启动iOS应用程序[iOS7和iOS8] - locationMangers(CLLocationManager)authorizationStatus预设为

authorizationStatus(CLAuthorizationStatus) = kCLAuthorizationStatusNotDetermined

在iOS7 +中提示

启动locationManger(CLLocationManager,Strong)并设置委托(CLLocationManagerDelegate)

现在提示用户使用位置服务并列出应用程序>隐私>位置服务下的应用程序,它必须调用任何位置服务方法,它取决于应用程序要求 - 例如,如果应用程序是以下类型之一

地点更新 - [self.locationManager startUpdatingLocation]

RegionMonitoring - [self.locationManager startMonitoringForRegion:beaconRegion]

在执行上述方法后,iOS将提示用户请求在应用程序中接受使用位置服务,无论用户选择应用程序将在"设置">"隐私">"位置服务"下列出.

在iOS8 +中提示

与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的屏幕截图(如果有人对此感到困惑) 在此输入图像描述

6 个回答
  • 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
    
    }
    

    2023-02-09 13:36 回答
  • 我遇到了同样的问题,在重新安装我的应用程序之后,kCLAuthorizationStatusNotDetermined每当检查时它都会返回,[CLLocationManager authorizationStatus]并且应用程序甚至没有显示在"设置">"隐私">"位置服务"中.

    将触发iOS提示用户批准访问位置服务的授权对话框,在[locationManager startUpdatingLocation]此情况下永远不会调用(shouldFetchUserLocation将始终NO).

    米格尔C.的解决方案似乎是一个很好的解决方案,将尝试.

    编辑iOS8.x

    当iOS8出现时,它对CLLocationManager的使用方式几乎没有任何改变.正如在其他答案中提到的那样,与iOS7相比,它需要额外的步骤.今天我自己遇到了这个问题并找到了这篇文章(它已经从多个其他问题中引用,但它完成了我之前的回答).希望能帮助到你!

    2023-02-09 13:36 回答
  • iOS8通过LocationsServices为我们带来了主要的API更改

    假设 [CLLocationManager locationServicesEnabled]返回YES,

    首次启动iOS应用程序[iOS7和iOS8] - locationMangers(CLLocationManager)authorizationStatus预设为

    authorizationStatus(CLAuthorizationStatus) = kCLAuthorizationStatusNotDetermined
    

    在iOS7 +中提示

    启动locationManger(CLLocationManager,Strong)并设置委托(CLLocationManagerDelegate)

    现在提示用户使用位置服务并列出应用程序>隐私>位置服务下的应用程序,它必须调用任何位置服务方法,它取决于应用程序要求 - 例如,如果应用程序是以下类型之一

    地点更新 - [self.locationManager startUpdatingLocation]

    RegionMonitoring - [self.locationManager startMonitoringForRegion:beaconRegion]

    在执行上述方法后,iOS将提示用户请求在应用程序中接受使用位置服务,无论用户选择应用程序将在"设置">"隐私">"位置服务"下列出.

    在iOS8 +中提示

    与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的屏幕截图(如果有人对此感到困惑) 在此输入图像描述

    2023-02-09 13:36 回答
  • 你一定是NSLocationWhenInUseUsageDescription加了你的info.plist.它有点奇怪,但只是添加为没有文本的字符串值,然后当你想要位置开始时:

    CLLocationManager * locationManager = [[CLLocationManager alloc] init];
    
    [locationManager requestWhenInUseAuthorization];
    

    2023-02-09 13:36 回答
  • 在iOS 8中,您需要做两件额外的事情才能使位置正常工作:在Info.plist中添加一个密钥,并向位置管理员请求授权以启动它.新位置授权有两个Info.plist键.需要这些键中的一个或两个.如果两个键都不存在,则可以调用startUpdatingLocation,但位置管理器实际上不会启动.它也不会向委托发送失败消息(因为它从未启动过,它不会失败).如果您添加一个或两个密钥但忘记明确请求授权,它也将失败.

    因此,您需要做的第一件事是将以下一个或两个密钥添加到Info.plist文件中:

    NSLocationWhenInUseUsageDescription
    NSLocationAlwaysUsageDescription
    

    这两个键都带有一个字符串,它描述了您需要位置服务的原因.您可以输入一个字符串,如"需要位置以查找您所在的位置",如iOS 7中所示,可以在InfoPlist.strings文件中进行本地化.

    接下来,您需要请求相应位置方法,WhenInUse或Background的授权.使用以下电话之一:

    [self.locationManager requestWhenInUseAuthorization]
    [self.locationManager requestAlwaysAuthorization]
    

    有关更多信息.

    2023-02-09 13:36 回答
  • 如果您在iOS8上遇到此问题,请使用:requestWhenInUseAuthorization.

    2023-02-09 13:37 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有