位置情報サービスがiOS 8で機能しない


608

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

CLLocationManager位置情報が返されず、[設定] -> [ 位置情報サービス]にもアプリが表示されません。この問題についてGoogleで検索しましたが、何も見つかりませんでした。何が悪いのでしょうか?



19
iOS 8でのロケーションマネージャーの変更点のいくつかをここに投稿し
nevan king

2
コアロケーションAPIを簡素化し、素敵なブロックベースのインターフェイスを公開し、異なるiOSバージョン間のすべての違いを正規化するこのライブラリを使用してみてください(完全な開示:私は作者です):github.com/lmirosevic/GBLocation
lms

私はここにいくつかの参照を見つけたdatacalculation.blogspot.in/2014/11/...
iOSのテスト

2
@nevankingありがとうございます!王冠が必要です!私は変更以来、この問題に取り組んできましたが、それを修正するための「ガイド」をまだ見つけていません。それは初心者にやさしいものでした。リンクありがとうございます。
Patrick R

回答:


1086

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

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

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

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

それが他の誰かを助けることを願っています。

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


6
Info.plistで更新された正確な評価者を共有できますか?IamがInfo.plistでそのキーを表示できません。追加しましたが、動作しないようです。私は6ベータ4スウィフト、iOS8とXcodeを使用しています
ビジェイ・クマールAB

4
@Vjay-エディターでInfo.plistファイルを編集する必要があります。Xcodeでこれらのキーを設定できません(ベータ6以降)。
Kendall Helmstetter Gelner 2014

11
リマインダーです。ユーザーにカスタムの説明を表示したくない場合は、このキーを空の文字列に設定してください。
nonamelive 2014

7
機能させるには、locationManagerを保持する必要があります。CLLocationManagerを強力なプロパティとして作成します
Vassily

273
plistエントリを省略しても、エラー、警告、ログメッセージは表示されず、何も発生しないことを「愛しています」。基本的にAppleは、適切なplistエントリがない場合は何もしないAPI呼び出しを作成しました。これを理解してくれた@OrtwinGentzに感謝します。
MobileVet 2014

314

同じ問題で髪を抜いていた。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でこのプロジェクトを開始してからこれらのエントリが欠落している可能性があると思います。Xcode6がこれらのキーのデフォルトエントリを追加する可能性があると思いますが、確認していません。

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


13
xcode 6はデフォルトでこれらのキーを追加しません。CLLocationManagerを実装する場合は、手動で追加する必要があります
Wesley Smith

1
これらも手動で追加する必要があり、Xcode6のinfo.plistのRawValuesビューから追加できませんでした。
Kendall Helmstetter Gelner 2014

1
私はこれを永遠に探しました。[CLLLocationManager authorizationStatus]メッセージが<nil>の値のみを返していました。上記のキーを追加した後、メッセージの出力に対してそれぞれの列挙を返し始めました。私が見つけたものから、これはiOS 8の既知のバグですが、私の時代の中で何も見つかりませんでした。ミルありがとう!
MrOli3000

4
あなたが入力した文字列値が好きです
Chris Chen

1
メッセージは、ユーザーが現在地を共有するかどうかを尋ねるアラートのサブメッセージとして表示されます。そのため、私のアプリケーションでは単に空(空白)であることが最も理にかなっているようです。場所を使用する理由の説明も意味があります。ただし、NSLocationWhenInUseUsageDescriptionは期待どおりに動作しませんでした(つまり、戻り値が正しいにもかかわらず、アクセス許可が拒否され続けました)。NSLocationAlwaysUsageDescriptionは正常に機能しました。
アーカディボブ、2014

104

これが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];

164
バージョンをチェックするよりも良い方法は、オブジェクトにそのセレクターがあるかどうかをチェックすることです。例: if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) { ...
progrmr

1
Xcode 5でビルドするときに@progrmrのソリューションを実装するだけでは問題がありました。Xcode5 requestAlwaysAuthorizationは、メソッドが何であるかわからないためです。私の追加の解決策はif、通常のメソッド呼び出しの代わりに、ステートメントでこの行を使用することでした:[self.locationManager performSelector:@selector(requestAlwaysAuthorization)];。これは他の人には自明かもしれませんが、理解するのにしばらく時間がかかりました。最終的なXcode 6がリリースされるまで、これは適切なソリューションだと思います。
VinceFior 2014

2
適切なソリューションは、Xcode 6を使用してビルドすることです。Xcode5を使用してビルドしている場合、承認を要求する必要はなく、自動的に行われます。
progrmr 2014

ポイントがあるかもしれません。私の懸念は、チームがXcode 6に移行している間、コードをXcode 5でコンパイルしたい(Xcode 6でコンパイルしない限り、iOS 8では機能しない)ことでしたが、通常のコードを記述して、 Xcode 6.に移行するまではマージしないでください。ありがとうございます。
VinceFior 2014

@VinceFiorの推奨アプローチは、SDKで定義されたマクロ__IPHONE_OS_VERSION_MAX_ALLOWED#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000)を使用して条件付きでコンパイルすることです
Steven Kramer

50
- (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ファイルに ここに画像の説明を入力してください



2
@Hemang:Apple Dev Documentationによると:アプリの認証ステータスが決定される前に位置情報サービスを開始しても安全です。位置情報サービスを開始できますが、これらのサービスは、認証ステータスがkCLAuthorizationStatusAuthorizedAlwaysまたはkCLAuthorizationStatusAuthorizedWhenInUseに変更されるまでデータを配信しません。
Andrew

少し遅れて、私はあなたがあなたのplistファイル、特にFacebookAppIDの関係ない部分隠すお勧めします
はPrzemyslawWrzesiński

ありがとうしかし、それは単なるダミーサンプルです:)
neo D1

また、プロジェクトが正しい info.plist(キーが定義されているもの)を指していることも重要です。これは、Info.plistファイルのプロジェクトビルド設定で決定されます。
クリアライト16

30

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

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

ユーザーが許可を与える場合、それは通常通りの仕事です。許可を拒否した場合、代理人は位置の更新について通知されません。



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

  • NSLocationWhenInUseUsageDescription
  • NSLocationAlwaysUsageDescription

これらのキーは両方とも文字列を取ります

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

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


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

2
すべてのアプリで使用できる素晴らしいダイナミックソリューション。ただし、順序を変更し、iphone 8.0をチェックする代わりに、ロケーションマネージャーが認証に応答するかどうかをチェックしてから、authorizationstatusを実行してコードを取得します。これにより、より普遍的になります。
zirinisp 2014年

xCode 7.2でも動作しました。
Totoro

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

UIAlertViewは非推奨になりました。代わりにUIAlertControllerを使用する必要があります。
Pasan Premaratne 2014年

ええ、私はその非推奨を知っていますが、これも機能します。しかし、はい、IOS8にはUIAlertControllerを使用する方が適切です。
Nits007ak 2014年

12

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

1
疑似コードがプリプロセッサ呼び出しなのか通常の呼び出しなのか明確ではありません
El Dude

1
これをconstants.hまたは.pchファイルに追加します。#define IS_OS_8_OR_LATER([[UIDevice currentDevice] .systemVersion floatValue]> = 8.0)
OxenBoxen

なぜ両方を要求するのか、アプリケーションのニーズに応じてどちらか一方のみを使用することを言及するコメントを追加する必要があります
powerj1984

info.plist部分はUnity3dで実行するのに十分簡単ですが、unity3dを使用する場合、コード部分をどのように追加しますか?どこ ?
クトゥルフジョン2015

11

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

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

あなたがいる場合は、まだウィンドウが承認を求めポップアップ表示を見ていない、あなたがラインを入れているかどうかを確認しますvar locationManager = CLLocationManager()あなたのビューコントローラの中でviewDidLoadメソッド。その場合、を呼び出してlocationManager.requestWhenInUseAuthorization()も何も表示されません。これは、viewDidLoadの実行後、locationManager変数の割り当てが解除される(クリアされる)ためです。

解決策はvar locationManager = CLLocationManager()、クラスメソッドの上部に行を配置することです。


9

の前[locationManager startUpdatingLocation];に、iOS8位置情報サービス要求を追加します。

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

アプリを編集し、ユーザーに表示される文字列値でInfo.plistキーNSLocationAlwaysUsageDescriptionを追加します(たとえば、We do our best to preserve your battery life.

アプリが開いているときにのみアプリが位置情報サービスを必要とする場合は、次のものを置き換えます。

requestAlwaysAuthorizationrequestWhenInUseAuthorization

NSLocationAlwaysUsageDescriptionNSLocationWhenInUseUsageDescription


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

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


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キーを設定します


2
これは正しくありません。kCLAuthorizationStatusDeniedの場合はどうですか?それは他にジャンプし、正しくない場所の更新を開始します!
electronix384128 14

@BenMarten関係ないと思います。あなたはそれを自分で扱うべきlocationManager: (CLLocationManager *)manager didFailWithError: (NSError *)errorです。ただし、ifステートメントにstartUpdatingLocationを追加するのを忘れていたため、受諾または拒否した後、実際にはstartUpdateLocationが呼び出されません。
Chris

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つのキーと一緒に。


これは正しくありません。kCLAuthorizationStatusDeniedの場合はどうですか?それは他にジャンプし、正しくない場所の更新を開始します!
electronix384128 14

これはかなり奇妙です、これは私にとってはうまく機能しますが、許可と許可の両方で完全にうまく機能するわけではありません。奇妙ですが、うまくいきました!!!
ジョシュ2014

requestWhenInUseAuthorizationが無意味な直後に[self.locationManager startUpdatingLocation]を呼び出す
Kostia Kim

5

これはiOS 8の問題ですこれをコードに追加してください

if (IS_OS_8_OR_LATER)
{
    [locationmanager requestWhenInUseAuthorization];

    [locationmanager requestAlwaysAuthorization];
}

そして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>

NSLocationUsageDescriptioniOS8以降では使用されません
Carlos Ricardo

4

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

NSLocationAlwaysUsageDescription in the Info.plist 

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


4

Objective-Cの手順 以下の指示に従ってください。

iOS-11の 場合iOS 11の場合、この回答を確認してください:iOS 11の位置情報アクセス

2つのキーをplistに追加し、以下の画像のようにメッセージを提供する必要があります。

 1. NSLocationAlwaysAndWhenInUseUsageDescription 
 2. NSLocationWhenInUseUsageDescription
 3. NSLocationAlwaysUsageDescription

ここに画像の説明を入力してください 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の位置情報アクセス

2つのキーをplistに追加し、以下の画像のようにメッセージを提供する必要があります。

 1. NSLocationAlwaysAndWhenInUseUsageDescription 
 2. NSLocationWhenInUseUsageDescription
 3. NSLocationAlwaysUsageDescription

ここに画像の説明を入力してください 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

}

NSLocationAlwaysUsageDescriptionも追加されていることを確認してください。追加されていない場合は、App Storeへのアップロード中にエラーが発生します。
Alok、

あなたのメッセージも参考になるはずです。そうでなければ、アップルはプロセスを復活させている間、アプリを拒否します。
Alok、

3

Xamarinを使用している場合は、キーNSLocationWhenInUseUsageDescriptionをinfo.plistに手動で追加する必要がありました。これは、Xamarin 5.5.3 Build 6またはXCode 6.1のドロップダウンでは使用できなかっNSLocationUsageDescriptionたため、リストにのみ含ま れていたCLLocationManagerため、黙って失敗する。


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

}

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' {} 

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



2

iOS9で同様のエラーが発生します(Xcode 7およびSwift 2で動作): 位置認証を要求せずにMapKit位置更新を開始しようとしています。最初に-[CLLocationManager requestWhenInUseAuthorization]または-[CLLocationManager requestAlwaysAuthorization]を呼び出す必要があります。 私はチュートリアルに従っていましたが、講師はiOS8とSwift 1.2を使用していました。Xcode 7とSwift 2にはいくつかの変更点があります。このコードを見つけたので、うまく動作します(誰かが助けを必要とする場合):

import UIKit
import MapKit
import CoreLocation

class MapViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {

    // MARK: Properties
    @IBOutlet weak var mapView: MKMapView!

    let locationManager = CLLocationManager()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.locationManager.delegate = self
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
        self.locationManager.requestWhenInUseAuthorization()
        self.locationManager.startUpdatingLocation()
        self.mapView.showsUserLocation = true

    }

    // MARK: - Location Delegate Methods

    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let location = locations.last
        let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
        let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 1, longitudeDelta: 1))
        self.mapView.setRegion(region, animated: true)
    }

    func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
        print("Errors: " + error.localizedDescription)
    }
}

最後に、それをinfo.plistに入れます:情報プロパティリスト:NSLocationWhenInUseUsageDescription 値:アプリにはスタッフ用のロケーションサーバーが必要です


2

iOSでユーザーの場所にアクセスするため。2つのキーを追加する必要があります

NSLocationWhenInUseUsageDescription

NSLocationAlwaysUsageDescription

Info.plistファイルに。

    <key>NSLocationWhenInUseUsageDescription</key>
    <string>Because I want to know where you are!</string>
    <key>NSLocationAlwaysUsageDescription</key>
    <string>Want to know where you are!</string>

下の画像をご覧ください。

Info.plist画像


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各ターゲットのそれぞれにない場合、アプリはユーザーに確認しません。ifiOSの7との互換性を提供し、respondsToSelector:この方法は、単にiOSの7と8のための問題を解決するのではなく、将来の互換性を保証しています。


0

私にとっての問題は、そのクラスCLLocationManagerDelegateがプライベートであり、すべてのデリゲートメソッドが呼び出されないことでした。それは非常に一般的な状況ではないと思いますが、それが誰かを助ける場合に備えて私はそれを言及したいと思いました。


0

これらのキーをiOS 8.4、iPad mini 2に追加しInfoPlist.stringsました。のように、にキーを設定していません。NSLocationWhenInUseUsageDescriptionInfo.plist


InfoPlist.strings

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

このスレッドas in iOS 7基づくと、InfoPlist.stringsでローカライズできます。私のテストでは、これらのキーをファイルで直接構成できますInfoPlist.strings

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

  • NSLocationWhenInUseUsageDescription
  • NSLocationAlwaysUsageDescription

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


更新:

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.