[objective-c] iOS 8에서 작동하지 않는 위치 서비스

iOS 7에서 제대로 작동하는 내 앱은 iOS 8 SDK에서 작동하지 않습니다.

CLLocationManager위치를 반환하지 않으며 설정 -> 위치 서비스 에도 내 앱이 표시되지 않습니다 . 문제에 대한 Google 검색을 수행했지만 아무 것도 나타나지 않았습니다. 무엇이 잘못 될 수 있습니까?



답변

나는 내 자신의 문제를 해결하게되었습니다.

위치 업데이트를 시작하기 전에 iOS 8 SDK에서 requestAlwaysAuthorization(배경 위치의 경우) 또는 requestWhenInUseAuthorization(전경의 경우에만 위치) 호출 CLLocationManager이 필요합니다.

프롬프트에 표시 할 메시지 가 NSLocationAlwaysUsageDescription있거나 NSLocationWhenInUseUsageDescriptionInfo.plist를 입력해야합니다. 이것들을 추가하면 내 문제가 해결되었습니다.

여기에 이미지 설명을 입력하십시오

그것이 다른 누군가를 돕기를 바랍니다.

편집 : 자세한 내용은 다음을 참조하십시오 : Core-Location-Manager-Changes-in-ios-8


답변

나는 같은 문제로 머리카락을 뽑고있었습니다. Xcode는 당신에게 오류를 제공합니다 :

MapKit위치 승인을 요구하지 않고 위치 업데이트 를 시작하려고합니다 . 호출해야합니다 -[CLLocationManager
requestWhenInUseAuthorization]
또는 -[CLLocationManager
requestAlwaysAuthorization]
첫째.

그러나 위의 방법 중 하나를 구현하더라도 info.plist에 NSLocationAlwaysUsageDescription또는 에 대한 항목이 없으면 사용자에게 프롬프트하지 않습니다 NSLocationWhenInUseUsageDescription.

info.plist에 다음 행을 추가하십시오. 여기서 문자열 값은 사용자 위치에 액세스해야하는 이유를 나타냅니다.

<key>NSLocationWhenInUseUsageDescription</key>
<string>This application requires location services to work</string>

<key>NSLocationAlwaysUsageDescription</key>
<string>This application requires location services to work</string>

Xcode 5 에서이 프로젝트를 시작한 이후 이러한 항목이 누락되었을 수 있습니다. Xcode 6 이이 키에 대한 기본 항목을 추가 할 수는 있지만 추측하지 못했습니다.

이 두 설정에 대한 자세한 내용은 여기를 참조하십시오.


답변

이것이 iOS 7과 호환되는지 확인하려면 사용자가 iOS 8 또는 iOS 7을 실행 중인지 확인해야합니다. 예를 들면 다음과 같습니다.

#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)

//In ViewDidLoad
if(IS_OS_8_OR_LATER) {
   [self.locationManager requestAlwaysAuthorization];
}

[self.locationManager startUpdatingLocation];


답변

- (void)startLocationManager
{
    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.distanceFilter = kCLDistanceFilterNone; //whenever we move
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;

    [locationManager startUpdatingLocation];
    [locationManager requestWhenInUseAuthorization]; // Add This Line


}

info.plist 파일로
여기에 이미지 설명을 입력하십시오


답변

애플 문서에 따르면 :

iOS 8 부터는 앱의 Info.plist 파일 에 a NSLocationWhenInUseUsageDescription또는 NSLocationAlwaysUsageDescription키 값이 있어야합니다. 그런 다음 전화로 [self.myLocationManager requestWhenInUseAuthorization]또는 [self.myLocationManager requestAlwaysAuthorization]필요에 따라 위치 업데이트를 등록하기 전에 사용자에게 권한을 요청 해야합니다. 그러면 Info.plist에 입력 한 문자열이 다음 대화 상자에 표시됩니다.

사용자가 권한을 부여하면 평상시와 동일합니다. 권한을 거부하면 대리인에게 위치 업데이트를 알리지 않습니다.


답변

- (void)viewDidLoad
{

    [super viewDidLoad];
    self.locationManager = [[CLLocationManager alloc] init];

    self.locationManager.delegate = self;
    if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]){
        NSUInteger code = [CLLocationManager authorizationStatus];
        if (code == kCLAuthorizationStatusNotDetermined && ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)] || [self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])) {
            // choose one request according to your business.
            if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"]){
                [self.locationManager requestAlwaysAuthorization];
            } else if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) {
                [self.locationManager  requestWhenInUseAuthorization];
            } else {
                NSLog(@"Info.plist does not contain NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription");
            }
        }
    }
    [self.locationManager startUpdatingLocation];
}

>  #pragma mark - CLLocationManagerDelegate

    - (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 didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
    {
        NSLog(@"didUpdateToLocation: %@", newLocation);
        CLLocation *currentLocation = newLocation;

        if (currentLocation != nil) {
            longitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];
            latitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
        }
    }

iOS 8에서는 위치 작업을 수행하기 위해 두 가지 추가 작업을 수행해야합니다. Info.plist에 키를 추가하고 위치 관리자에게 시작을 요청하는 권한 부여를 요청하십시오. 새로운 위치 인증을위한 두 개의 Info.plist 키가 있습니다. 이 키 중 하나 또는 둘 다 필요합니다. 키가 없으면 startUpdatingLocation을 호출 할 수 있지만 위치 관리자는 실제로 시작되지 않습니다. 시작하지 않았기 때문에 실패 할 수 없으므로 실패 메시지를 대리인에게 보내지 않습니다. 키 중 하나 또는 둘 다를 추가했지만 명시 적으로 권한 부여를 요청하지 않으면 실패합니다. 따라서 가장 먼저해야 할 일은 Info.plist 파일에 다음 키 중 하나 또는 둘 다를 추가하는 것입니다.

  • NSLocationWhenInUseUsageDescription 설명
  • NSLocation 항상 사용법 설명

이 두 키는 모두 문자열을 취합니다.

위치 서비스가 필요한 이유에 대한 설명입니다. iOS 7에서와 같이 InfoPlist.strings 파일에서 현지화 할 수있는 “현재 위치를 확인하려면 위치가 필요합니다”와 같은 문자열을 입력 할 수 있습니다.

여기에 이미지 설명을 입력하십시오


답변

Xcode 5에서 컴파일 할 수있는 내 솔루션 :

#ifdef __IPHONE_8_0
    NSUInteger code = [CLLocationManager authorizationStatus];
    if (code == kCLAuthorizationStatusNotDetermined && ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)] || [self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])) {
        // choose one request according to your business.
        if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"]){
            [self.locationManager requestAlwaysAuthorization];
        } else if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) {
            [self.locationManager  requestWhenInUseAuthorization];
        } else {
            NSLog(@"Info.plist does not contain NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription");
        }
    }
#endif
    [self.locationManager startUpdatingLocation];