Programing

iOS : 앱을 설치하는 동안 앱이 사용자의 권한을 요청하지 않습니다.

crosscheck 2020. 10. 31. 09:22
반응형

iOS : 앱을 설치하는 동안 앱이 사용자의 권한을 요청하지 않습니다. 매번 kCLAuthorizationStatusNotDetermined 받기-Objective-c & Swift


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;
    }
}

나는 같은 문제에 직면했다. 내 앱을 다시 설치 한 후 kCLAuthorizationStatusNotDetermined확인할 때마다 반환 [CLLocationManager authorizationStatus]되고 앱이 설정> 개인 정보> 위치 서비스에 표시되지 않았습니다.

iOS에서 사용자에게 위치 서비스에 대한 액세스를 승인하라는 메시지를 표시하는 인증 대화 상자가 트리거 [locationManager startUpdatingLocation]되며 귀하의 경우에는 호출되지 않습니다 ( shouldFetchUserLocation항상 NO).

Miguel C.의 솔루션이 좋은 해결책 인 것 같습니다. 시도해 볼 것입니다.

iOS8.x 용 편집

iOS8이 출시되었을 때 CLLocationManager가 사용되는 방식에 거의 변화가 없었습니다. 다른 답변에서 몇 번 언급했듯이 iOS7과 비교하여 추가 단계가 필요합니다. 오늘 나는 직접 문제에 직면 하여이 기사를 발견했습니다 (다른 여러 질문에서 참조되었지만 이전 답변을 완료했습니다). 도움이 되었기를 바랍니다.


iOS8은 LocationsServices를 통해 API를 크게 변경했습니다.

[CLLocationManager locationServicesEnabled]return YES 라고 가정하고 ,

iOS 앱 [iOS7 및 iOS8 모두]의 최초 출시-locationMangers (CLLocationManager) authorizationStatus는

authorizationStatus(CLAuthorizationStatus) = kCLAuthorizationStatusNotDetermined

iOS7 +에서 프롬프트

locationManger (CLLocationManager, Strong)를 시작하고 델리게이트 (CLLocationManagerDelegate)를 설정합니다.

이제 사용자에게 위치 서비스를 사용하라는 메시지를 표시하고 설정> 개인 정보> 위치 서비스 아래에 앱을 나열하려면 위치 서비스 방법 중 하나를 호출해야합니다. 앱 요구 사항에 따라 다릅니다. 예를 들어 앱이 아래 중 하나 인 경우

위치 업데이트- [self.locationManager startUpdatingLocation]

지역 모니터링- [self.locationManager startMonitoringForRegion:beaconRegion]

위의 방법을 실행 한 직후 iOS는 앱에서 위치 서비스 사용을 수락하도록 사용자에게 요청하는 메시지를 표시하며 사용자 선택 앱과 관계없이 설정> 개인 정보> 위치 서비스 아래에 나열됩니다.

iOS8 +에서 프롬프트

iOS8과 동일한 경우에 앱 위치 서비스가 처음 시작되었습니다.

authorizationStatus(CLAuthorizationStatus) = kCLAuthorizationStatusNotDetermined

iOS 8에는 사용자에게 프롬프트를 표시하는 새로운 방법이 있습니다.

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

requestAlwaysAuthorization / requestWhenInUseAuthorization은 iOS8에서 사용할 수 있습니다. 앱 배포 대상이 iOS7이면이를 if 블록 아래에 래핑 하여 iOS7에서 앱 충돌로 이어지지 않도록합니다.

if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)])
{
[self.locationManager requestAlwaysAuthorization]; .
}

또는

if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])
{
[self.locationManager requestWhenInUseAuthorization];
}

매우 중요 ###:

iOS8에 따라 앱이 info.plist에 requestAlwaysAuthorization / requestWhenInUseAuthorization을 사용하는 이유를 설명하는 문자열을 포함하는 것은 필수입니다. 앱의 요구 사항에 따라 이러한 속성을 포함합니다.

kCLAuthorizationStatusAuthorizedAlways 포함 키 / 값 (문자열 값) 쌍

NSLocationAlwaysUsageDescription = App use Locations service mode Always

kCLAuthorizationStatusAuthorizedWhenInUse의 경우 키 / 값 (문자열 값) 쌍 포함

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];
}

스위프트 코드

아래 지침을 따르십시오.

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

}

NSLocationWhenInUseUsageDescription추가 해야합니다 info.plist. 조금 이상하지만 텍스트가없는 문자열 값으로 추가 한 다음 위치를 다음으로 시작하려면 다음과 같이하십시오.

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

[locationManager requestWhenInUseAuthorization];

iOS8에서이 문제가 발생하면 : requestWhenInUseAuthorization을 사용 하십시오.


iOS 8에서 위치를 작동하려면 두 가지 추가 작업을 수행해야합니다. Info.plist에 키를 추가하고 시작을 요청하는 위치 관리자에게 인증을 요청합니다. 새 위치 인증을위한 두 개의 Info.plist 키가 있습니다. 이 키 중 하나 또는 모두가 필요합니다. 두 키가 모두 없으면 startUpdatingLocation을 호출 할 수 있지만 위치 관리자가 실제로 시작되지는 않습니다. 대리자에게도 실패 메시지를 보내지 않습니다 (시작되지 않았으므로 실패 할 수 없습니다). 키 중 하나 또는 둘 모두를 추가했지만 명시 적으로 인증을 요청하는 것을 잊은 경우에도 실패합니다.

따라서 가장 먼저해야 할 일은 Info.plist 파일에 다음 키 중 하나 또는 둘 모두를 추가하는 것입니다.

NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription

두 키 모두 위치 서비스가 필요한 이유를 설명하는 문자열을 사용합니다. iOS 7에서와 같이 InfoPlist.strings 파일에서 현지화 할 수있는 "현재 위치를 찾으려면 위치가 필요합니다."와 같은 문자열을 입력 할 수 있습니다.

다음으로 해당 위치 방법 인 WhenInUse 또는 Background에 대한 인증을 요청해야합니다. 다음 호출 중 하나를 사용하십시오.

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

자세한 내용은 .


Rashmi Ranjan mallick이 iOS 7이 출시 된 이후 댓글에서 몇 번 언급 한 문제가있었습니다. 나는 정말로 iOS 7의 한 가지 버그라고 생각합니다. 그들은 새로운 버전의 iOS에 많은 버그가 있습니다.

나에게 문제는 동일했습니다.

1. 앱을 열고 위치를 묻지 않습니다. iOS는 권한에 대해 묻지 않았습니다 .2
. 설정-> 개인 정보-> 위치 서비스로 이동 했는데 앱이 없었습니다.
3. 어떤 식 으로든 내 앱의 위치 권한을 변경할 수 없습니다.

이에 대한 한 가지 해결 방법은 다음과 같습니다.

1. 앱을 종료하십시오.
2. 메인 스위치 버튼으로 모든 위치 서비스를 비활성화합니다.
3. 앱으로 다시 이동합니다.
4. 앱을 죽인다.
5. 이전 스위치 버튼에서 위치 서비스를 다시 활성화합니다.
6. 여전히 목록에 나타나지 않으면 앱으로 다시 이동하여 다시 종료하고 설정으로 돌아갑니다.
7. 이제 거기에 있어야합니다.

이것은 나를 위해 일했으며 이것이 유용하기를 바랍니다.

UPDATE : 경우 아이폰 OS 8 일 당신이 호출 requestWhenInUseAuthorization또는requestAlwaysAuthorization

You may follow this code: :)

#ifdef __IPHONE_8_0
    if(NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1)
    {
        if([[Wave_SettingsObject sharedObject] backgroundLocationEnabled].boolValue == YES)
        {
            if(![[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"])
            {
                NSLog(@"Info.plist does not contain NSLocationAlwaysUsageDescription key");
            }

            if ([locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) //iOS 8+
            {
                [locationManager requestAlwaysAuthorization];
            }
        }
        else if([[Wave_SettingsObject sharedObject] isLocationEnabled].boolValue == YES)
        {
            if(![[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"])
            {
                NSLog(@"Info.plist does not contain NSLocationWhenInUseUsageDescription key");
            }

            if ([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) //iOS 8+
            {
                [locationManager requestWhenInUseAuthorization];
            }

        }
    }
#endif

Uninstall the app and try running it again.

If it didn't work, go to the settings and disable the authorization to that app. After that running it again to see if it asks permissions.

Or:

You can force the app start monitoring the location with some code like that:

self.locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];

in your delegate methods you can detect if there an error getting location and you can inform the user.

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    // Delegate of the location manager, when you have an error
    NSLog(@"didFailWithError: %@", error);

    UIAlertView *errorAlert = [[UIAlertView alloc]     initWithTitle:NSLocalizedString(@"application_name", nil) message:NSLocalizedString(@"location_error", nil) delegate:nil cancelButtonTitle:NSLocalizedString(@"ok", nil) otherButtonTitles:nil];

    [errorAlert show];
}

If you have any questions tell me.


Try adding

[locationManager startUpdatingLocation]

also make sure that location services is turned on.

EDIT:

Also try deleting the application and re-installing it. There may be a record of that the app is reading which is preventing it from asking for permission to use location.


When prompting for location you must not forget those things (iOS 8+):

  1. Add this flag on your info.plist of the app : NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription depend if you want always access to location or only when app is in usage (the second is recommended if you don't need always access). This is the most important because it is new and weird.
  2. If you request always permission don't forget to add location updates as background mode on your target capabilities
  3. Make sure you are asking for the right permission when initialise location manager:

    -(void)initLocationManager{
        locationManager = [[CLLocationManager alloc] init];
        locationManager.delegate=self;
    
        [locationManager requestAlwaysAuthorization]; // HERE ASK FOR THE RELEVANT
    }
    

For testing in simulator I suggest you to "Reset all content and settings" from it's options. That's the only way to get the exact same experience a new user of the app would get.


I ran into this issue, implemented all of the things necessary including the pList keys and my app was still not requesting location.

Turns out the issue was that the locationManager variable cannot be a local - it needs to be an instance variable.

So instead of

-(void) updateLocation {
   CLLocationManager *locationManager = ...
}

it needs to be:

CLLocationManager *locationManager;

-(void) updateLocation {
  self.locationManager = ...
}

I had a similar issue, but caused for a different reason. Adding it here in case it could help anyone else.

I stopped receiving the asking for authorization message, and since it was working before the requirements described in the other answers were already fulfilled: the key in the plist, checking authorization status and then asking for permission in ios8+.

제 경우에는 "액세스 가이드"모드와 관련된 문제였습니다. 이것은 키오스크 용 앱이며 "액세스 가이드"가 활성화 된 후에 만 ​​비콘 범위 지정을 시작합니다. 그러나이 모드에서는 인증 요청 메시지가 전송되지 않는 것 같습니다. 인증 요청 절차를 첫 번째 표시된보기의 DidLoad로 이동하기 만하면 문제를 해결할 수 있습니다.

카메라 사용 요청도 마찬가지입니다.

참고 URL : https://stackoverflow.com/questions/20664928/ios-app-is-not-asking-users-permission-while-installing-the-app-getting-kclau

반응형