現在地の許可ダイアログがすぐに消える


175

私のアプリはユーザーの現在地を取得し、座標を取得して、目的地や出発地までの距離を提供します。これらすべての可能な宛先はテーブルビューに表示されるため、テーブルにデータを入力すると同時にユーザーの座標を取得しています。唯一のことは、ユーザーの場所を尋ねるアラートビューが表示された後、すぐに消えてクリックできないことです。

アプリが最初に読み込まれたときにこのアラートを手動で表示する方法はありますか?アプリが読み込まれたときにユーザーの現在地を取得して、アラートを強制的に表示させようとしましたが、うまくいきませんでした。

回答:


698

追跡するのは難しいですが、これに対する解決策は非常に簡単です。

多くの試行錯誤の結果、アプリの位置情報サービスに初めてアクセスしようとすると位置情報アクセスダイアログがポップアップ表示されますが、次の場合はダイアログが自然に消えます(ユーザーの操作なし)。 CLLocationManagerされますがオブジェクトが前に解放されたユーザーはダイアログに応答します。

メソッドでCLLocationManagerインスタンスを作成していましたviewDidLoad。これはメソッドのローカルインスタンスであるため、メソッドの実行が完了した後で、インスタンスはARCによって解放されました。インスタンスが解放されるとすぐに、ダイアログは消えました。解決策はかなりシンプルでした。変更CLLocationManagerメソッドレベルの変数は、クラスレベルのインスタンス変数であるとされてからインスタンス。これで、CLLocationManagerクラスがアンロードされた後にのみインスタンスが解放されます。


117
私はあなたに+100を与えることができるといいのですが
コーダー

1
Xamarin.iOSでも同じ問題が発生します。CLLocationManagerクラスのスコープを作成すると、ダイアログは表示されたままになります。
Krumelur 14

1
あぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁ!(真剣に、これは私にとっても大きな節約です)
Garfonzo '25 / 11/14

2
私もこのパーティーに参加しなければなりません。ここで、私からインターネットハイファイブを入手してください!
Matthieu Riegler、2015年

3
Swiftでこの問題が発生した場合は、必ずLocationManagerの宣言をviewDidLoadの外に移動してください。乾杯!
KD。

5

同じ症状、異なる原因:連続して複数回呼び出さないでくださいstartUpdatingLocation

コードが意図せずに呼び出されるように誤って構造化した startUpdatingLocation 2回続けてしましたが、これは明らかに悪いことです。また、ネットワークリクエストの結果が出るまで更新を開始するのを待っていたため、キューの選択に何らかの影響があった可能性がありますが、GCDのマジックを実行して修正する必要はありませんでした。スタートを繰り返さなかった。

誰かが私の痛みから利益を得ることができることを願っています。:)


5

私も同じような状況に直面しています。デバッグした後、私は見つけました

let locationManager = CLLocationManager()

メソッドスコープで呼び出されますが、グローバルに呼び出す必要があります。

どうして?

一言で言えば、locationManagerはメソッドが戻った後にリリースされています。ただし、ユーザーが許可を与えるか拒否するまで、リリースしないでください。


4

私は同じ問題に陥ります(少なくとも症状によって)。私の場合、問題は- (void)applicationWillResignActive:(UIApplication *)application;メソッドにありCLLocationManager、バックグラウンドトランジションの準備の一環としてインスタンスを解放していました。取り外して放置しただけで- (void)applicationDidEnterBackground:(UIApplication *)application;問題はなくなりました。
トリッキーな部分は、Core Locationアラートがアプリケーションをフォアグラウンドで停止していることです。
それがあなたを助けることを願って、そのろくでなしを見つけるのに私に多くの時間をかけました:)


4

私はこれが非常に遅い返事であることを知っています。しかし、それは誰かを助けるかもしれません。私も同じ問題に直面し、問題を特定するために1時間を費やしました。最初、私のコードはこのようなものでした。

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

CLLocation *location = locationManager.location;
//my stuff with the location

    [locationManager release];

これで、ロケーションアラートがすばやく表示されました。最後の行のコメントを外すと、正しく機能しています。

   // [locationManager release];

3
これは本当です。この回答に追加する唯一の警告は、プロジェクトでARCが有効になっている場合、コードにリリースステートメントを含める必要がないため、この問題が引き続き発生することです。そのシナリオで問題を解決する唯一の方法は、変数をメソッドレベルではなくクラスレベルにすることです。
Zoli

3

私もこの問題に遭遇しましたが、私の場合の解決策は、受け入れられた回答とはまったく異なることがわかりました。

私のアプリでは、stopUpdatingLocationから呼び出していましたapplicationWillResignActiveapplicationWillResignActive許可ダイアログが表示されたときに呼び出されるため、これは問題でした。これはのstopUpdatingLocation直後に発生していたstartUpdatingLocationため、ダイアログはすぐに消えていました。

ソリューションは、コールに単純だったstopUpdatingLocationからapplicationDidEnterBackground代わりに。


2

これは、iOSシミュレーターを使用しているときに起こりました。Run Schemeがロケーションをシミュレーションしていたために発生していると判断しました。これはlocationManager.startUpdatingLocation()起動時に呼び出すのと同じ効果があると思いますので、ダイアログを閉じていました。

[スキームの編集]ダイアログの[ロケーションシミュレーションを許可]チェックボックスをオフにすると、問題が修正されました。期待どおりに動作し、権限が設定されたら、位置シミュレーションを再度有効にすると、シミュレータはそれ以降正常に動作します。


これは私にとってある程度うまくいきました。少なくともダイアログを見なければなりませんでした
CppChase 2017年

2

Swift 4およびiOS 11

必ずプライバシーライン(常に、およびwhenInUseの両方)を.plistファイルに追加し、CoreLocationフレームワークをプロジェクトに追加してください。

変更すると、場所の許可ダイアログが正しく表示されます:

locationManager.requestAlwaysAuthorization()

と:

locationManager.requestWhenInUseAuthorization()

PS。:すべてのアドバイスを試してみましたが、すべて失敗しました(locationManagerの代わりにに承認を要求しviewDidLoad、要求後に開始しないでください。バグだと思います。できるだけ早く解決してくれることを願っています。varletstartUpdatingLocation()


私もすべてのアドバイスに従いましたが、いつも同じ問題を抱えています。ロケーション許可ダイアログが短時間表示され、すぐに消えます。次に、通知ダイアログのアクセス許可が表示されます(これは正常です)。同意または拒否を押すと、他の場所のアクセス許可が表示されます(今回はそのままで、許可または拒否を許可します)。

@BitoQはい、私にとっても。同じような状況が、少なくとも、私たちは、このダイアログを見ることができ、私は...彼らはこのバグを修正します次のiOS 11.1と願っています
アレッサンドロオルナーノ

1

SWIFT 4 @Zoliソリューションは次のようになります。

class WhateverViewController: UIViewController {
    let locationManager = CLLocationManager() // here is the point of the @Zoli answer

    // some code
    override func viewDidLoad() {
        super.viewDidLoad()

        // some other code
        locationManager.requestWhenInUseAuthorization()
        // some other code
    }
}

0

ほとんどの場合、locationManager変数をグローバルオブジェクトとして定義します。

@interface ViewController : UIViewController
{
    CLLocationManager *locationManager;
}
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

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

0

私はあなたの同じ状況に会いました。

  • 私のソリューションは、ローカル変数からメンバーインスタンスに変更されました。
  • 原因は、ローカル変数を含むメソッドが終了した後、local?instanceが無効になったことです(私のlocationManagerの拡張)
  • 私の環境:Xcode9.3.1
#インポート 
@interface ViewController()

@終わり

@implementation ViewController
@synthesize locManager; //後
-(void)viewDidLoad {
    [super viewDidLoad];
    //ビューを読み込んだ後、通常はnibから追加の設定を行います。

    // MyLocationService * locManager = [[BSNLocationService alloc] init:nil]; // 前。場所。このメソッドの後でインスタンスが無効になったため、デリゲートは機能しませんでした。
    self-> locManager = [[MyLocationService alloc] init:nil]; //後
    locManager.startService;
}

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