618

iOS 7 では問題なく動作していたアプリが、iOS 8 SDK では動作しません。

CLLocationManager場所を返さないし、[設定] -> [位置情報サービス] にも自分のアプリが表示されません。この問題について Google で検索しましたが、何もヒットしませんでした。何が間違っている可能性がありますか?

4

26 に答える 26

1095

私は自分の問題を解決することになりました。

どうやら iOS 8 SDK では、requestAlwaysAuthorization(バックグラウンドの場所の場合) またはrequestWhenInUseAuthorization(フォアグラウンドの場合のみの場所) の呼び出しが、CLLocationManager場所の更新を開始する前に必要です。

また、プロンプトに表示されるメッセージを入力するか、入力するNSLocationAlwaysUsageDescription必要がありNSLocationWhenInUseUsageDescriptionます。Info.plistこれらを追加することで私の問題は解決しました。

ここに画像の説明を入力

より広範な情報については、以下をご覧ください: Core-Location-Manager-Changes-in-ios-8

于 2014-06-05T14:58:19.103 に答える
318

私は同じ問題で髪を引っ張っていました。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 ではこれらのキーのデフォルト エントリが追加される可能性があると思いますが、確認していません。

これら 2 つの設定の詳細については、こちらを参照してください。

于 2014-06-05T15:58:17.173 に答える
30

アップルのドキュメントによると:

iOS 8 以降、アプリの Info.plist ファイルにNSLocationWhenInUseUsageDescriptionまたはキー値が存在する必要があります。NSLocationAlwaysUsageDescriptionまた、位置情報の更新を登録する前に、電話[self.myLocationManager requestWhenInUseAuthorization]または必要に[self.myLocationManager requestAlwaysAuthorization]応じてユーザーに許可を求める必要があります。Info.plist に入力した文字列は、その後のダイアログに表示されます。

ユーザーが許可を与える場合は、通常どおりです。許可を拒否した場合、デリゲートには場所の更新が通知されません。

于 2014-06-08T22:16:08.220 に答える
28
- (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 では、位置情報を機能させるために、さらに 2 つのことを行う必要があります: Info.plist にキーを追加し、位置情報管理者に開始を求める承認を要求します。新しい場所の承認には、Info.plist キーが 2 つあります。これらのキーのいずれかまたは両方が必要です。どちらのキーも存在しない場合、startUpdatingLocation を呼び出すことはできますが、ロケーション マネージャーは実際には起動しません。デリゲートにも失敗メッセージは送信されません (開始されていないため、失敗することはありません)。キーの 1 つまたは両方を追加しても、承認を明示的に要求するのを忘れた場合にも失敗します。したがって、最初に行う必要があるのは、次のキーのいずれかまたは両方を Info.plist ファイルに追加することです。

  • NSLocationWhenInUseUsageDescription
  • NSLocationAlwaysUsageDescription

これらのキーはどちらも文字列を取ります

これは、位置情報サービスが必要な理由の説明です。iOS 7 と同様に、InfoPlist.strings ファイルでローカライズできる「現在地を調べるには場所が必要です」のような文字列を入力できます。

ここに画像の説明を入力

于 2014-12-17T03:26:32.483 に答える
19

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];
于 2014-09-24T12:13:05.330 に答える
17

位置を尋ねる古いコードは、iOS 8 では機能しません。位置認証には、次の方法を試すことができます。

- (void)requestAlwaysAuthorization
{
    CLAuthorizationStatus status = [CLLocationManager authorizationStatus];

    // If the status is denied or only granted for when in use, display an alert
    if (status == kCLAuthorizationStatusAuthorizedWhenInUse || status ==        kCLAuthorizationStatusDenied) {
        NSString *title;
        title = (status == kCLAuthorizationStatusDenied) ? @"Location services are off" :   @"Background location is not enabled";
        NSString *message = @"To use background location you must turn on 'Always' in the Location Services Settings";

        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
                                                            message:message
                                                           delegate:self
                                                  cancelButtonTitle:@"Cancel"
                                                  otherButtonTitles:@"Settings", nil];
        [alertView show];
    }
    // The user has not enabled any location services. Request background authorization.
    else if (status == kCLAuthorizationStatusNotDetermined) {
        [self.locationManager requestAlwaysAuthorization];
    }
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 1) {
        // Send the user to the Settings for this app
        NSURL *settingsURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
        [[UIApplication sharedApplication] openURL:settingsURL];
    }
}
于 2014-09-27T09:54:54.937 に答える
13

iOS 8 では、位置情報を機能させるために、さらに 2 つのことを行う必要があります: Info.plist にキーを追加し、位置情報管理者に開始を求める承認を要求します。

info.plist:

<key>NSLocationUsageDescription</key>
<string>I need location</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>I need location</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>I need location</string>

これをコードに追加します

if (IS_OS_8_OR_LATER)
{
    [locationmanager requestWhenInUseAuthorization];

    [locationmanager requestAlwaysAuthorization];
}
于 2014-10-02T06:40:00.460 に答える
11

Swift 開発者によくあるエラーの 1 つ:

NSLocationWhenInUseUsageDescription最初に、 または のいずれかの plist に値を追加してくださいNSLocationAlwaysUsageDescription

それでも承認を求めるウィンドウ ポップアップが表示されない場合は、View Controller のメソッドに行を追加しているかどうかを確認してvar locationManager = CLLocationManager()くださいviewDidLoad。そうすると、 を呼び出しlocationManager.requestWhenInUseAuthorization()ても何も表示されません。これは、viewDidLoad の実行後に locationManager 変数の割り当てが解除される (クリアされる) ためです。

var locationManager = CLLocationManager()解決策は、クラス メソッドの先頭にある行を見つけることです。

于 2015-02-17T22:40:17.870 に答える
9

iOS 8 にアップグレードされたアプリで作業していたところ、位置情報サービスが機能しなくなりました。おそらく、次のようにデバッグ領域でエラーが発生します。

Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.

私は最も邪魔にならない手順を実行しました。まずNSLocationAlwaysUsageDescription、info.plist にエントリを追加します。

ここに画像の説明を入力してください

このキーの値を入力していないことに注意してください。これはまだ動作します。これは社内アプリであるため、私は心配していません。また、位置情報サービスの利用を求めるタイトルがすでにあるので、余計なことはしたくなかった。

次に、iOS 8 の条件を作成しました。

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

この後、locationManager:didChangeAuthorizationStatus:メソッドが呼び出されます:

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:  (CLAuthorizationStatus)status
{
    [self gotoCurrenLocation];
}

そして今、すべてがうまくいきます。いつものように、ドキュメントをチェックしてください。

于 2014-11-24T16:14:05.550 に答える
7

下位互換性があるソリューション:

SEL requestSelector = NSSelectorFromString(@"requestWhenInUseAuthorization");
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined &&
    [self.locationManager respondsToSelector:requestSelector]) {
    [self.locationManager performSelector:requestSelector withObject:NULL];
} else {
    [self.locationManager startUpdatingLocation];
}

Info.plist で NSLocationWhenInUseUsageDescription キーを設定します

于 2014-09-11T05:22:19.730 に答える
6

Xcode の警告を生成しない下位互換性を備えたソリューション:

SEL requestSelector = NSSelectorFromString(@"requestWhenInUseAuthorization");
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined &&
  [self.locationManager respondsToSelector:requestSelector]) {
((void (*)(id, SEL))[self.locationManager methodForSelector:requestSelector])(self.locationManager, requestSelector);
  [self.locationManager startUpdatingLocation];
} else {
  [self.locationManager startUpdatingLocation];
}

NSLocationWhenInUseUsageDescriptionでキーをセットアップしますInfo.plist

iOS バージョン 11.0 以降のNSLocationAlwaysAndWhenInUseUsageDescription場合: Info.plist. 他の2つのキーと一緒に。

于 2014-09-11T09:30:59.890 に答える
4

iOS 8 でユーザーの場所にアクセスするには、追加する必要があります。

NSLocationAlwaysUsageDescription in the Info.plist 

これにより、ユーザーは現在の場所を取得する許可を求められます。

于 2014-11-17T04:49:38.010 に答える
2

複数の Info.plist ファイルを持っているすべての人のための小さなヘルパー...

find . -name Info.plist | xargs -I {} /usr/libexec/PlistBuddy -c 'Add NSLocationWhenInUseUsageDescription string' {} 

現在のディレクトリ (およびサブフォルダー) 内のすべての Info.plist ファイルに必要なタグが追加されます。

もう一つは:

find . -name Info.plist | xargs -I {} /usr/libexec/PlistBuddy -c 'Set NSLocationWhenInUseUsageDescription $YOURDESCRIPTION' {} 

すべてのファイルに説明が追加されます。

于 2014-10-07T08:18:12.890 に答える
2

Cocoa Keysの情報は、これらの更新のために常に手元に置いておいてください。リンクは次のとおりです。

https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW26

楽しみ。

于 2015-07-30T23:51:02.777 に答える
2
        // ** Don't forget to add NSLocationWhenInUseUsageDescription in MyApp-Info.plist and give it a string

        self.locationManager = [[CLLocationManager alloc] init];
        self.locationManager.delegate = self;
        // Check for iOS 8. Without this guard the code will crash with "unknown selector" on iOS 7.
        if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
            [self.locationManager requestWhenInUseAuthorization];
        }
        [self.locationManager startUpdatingLocation];


    // Location Manager Delegate Methods    
    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
    {
        NSLog(@"%@", [locations lastObject]);

}
于 2014-11-18T13:50:09.900 に答える
1
  1. キーNSLocationWhenInUseUsageDescriptionまたはNSLocationAlwaysUsageDescription(バックグラウンド GPS 使用) を追加info.plistし、各ターゲットからそれぞれに GPS を使用するように求める文字列を追加します。

  2. 次を実行して許可を求めます。

    [self initLocationManager:locationManager];

どこinitLocationManagerにある:

// asks for GPS authorization on iOS 8
-(void) initLocationManager:(CLLocationManager *) locationManager{

    locationManager = [[CLLocationManager alloc]init];

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

キーがinfo.plist各ターゲットのそれぞれにない場合、アプリはユーザーに尋ねないことに注意してください。ifは iOS 7 との互換性を提供し、この方法respondsToSelector:は iOS 7 および 8 の問題を解決するだけでなく、将来の互換性を保証します。

于 2014-11-16T22:04:17.700 に答える
0

InfoPlist.stringsこれらのキーをiOS 8.4、iPad mini 2に追加しました。これも機能します。NSLocationWhenInUseUsageDescriptionのようなキーは設定しませんInfo.plist


InfoPlist.strings :

"NSLocationWhenInUseUsageDescription" = "I need GPS information....";

このスレッドas in iOS 7に基づいて、InfoPlist.strings でローカライズできると述べています。私のテストでは、これらのキーは file で直接構成できますInfoPlist.strings

したがって、最初に行う必要があるのは、次のキーの 1 つまたは両方を > Info.plist ファイルに追加することです。

  • NSLocationWhenInUseUsageDescription
  • NSLocationAlwaysUsageDescription

これらのキーはどちらも、位置情報サービスが必要な理由を説明する文字列を取ります。iOS 7のように、InfoPlist.strings ファイルでローカライズできる「現在地を調べるには場所が必要です」のような文字列を入力できます。


アップデート:

@IOSの方法が良いと思います。キーをInfo.plist空の値とともに追加し、ローカライズされた文字列を に追加しますInfoPlist.strings

于 2015-07-30T09:58:01.870 に答える