web-dev-qa-db-ja.com

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

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

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

161
glenn sayers

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

多くの試行錯誤を通して、アプリ内の位置情報サービスに初めてアクセスしようとすると位置情報アクセスダイアログが表示されますが、CLLocationManagerオブジェクトは、ユーザーがダイアログに応答する前に解放されます。

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

644
Zoli

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

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

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

5
clozach

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

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

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

    [locationManager release];

これで、ロケーションアラートはすぐに消えました。最後の行のコメントを外すと、正常に機能しています。

   // [locationManager release];
4
Ramaraj T

私は同じ問題に陥ります(少なくとも症状によって)。私の場合、問題は- (void)applicationWillResignActive:(UIApplication *)application;メソッドにあり、そこではバックグラウンド移行の準備の一環としてCLLocationManagerインスタンスをリリースしていました。削除して- (void)applicationDidEnterBackground:(UIApplication *)application;のみに残した場合、問題はなくなりました。
注意が必要なのは、コアロケーションアラートがアプリケーションをフォアグラウンドにある間中断することです。
それがあなたを助けることを願っています、私がそのろくでなしを見つけるのに多くの時間がかかりました:)

4
Ariel

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

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

解決策は、代わりにstopUpdatingLocationからapplicationDidEnterBackgroundを呼び出すことです。

3
Alan Kinnaman

Swift 4およびiOS 11

必ずプライバシー行(alwayswhenInUse)の両方を追加してください_.plist_ファイルを作成し、CoreLocation Frameworkをプロジェクトに追加します

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

_locationManager.requestAlwaysAuthorization()
_

で:

_locationManager.requestWhenInUseAuthorization()
_

PS .:試しました[〜#〜] all [〜#〜]アドバイスとすべて失敗(viewDidLoadvar locationManagerのletの代わりに、リクエスト後にstartUpdatingLocation()を開始しないでください。これはバグだと思うので、できるだけ早く解決することを願っています。

2

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

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

2
Paolo

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
    }
}
1
wm.p1us

私は同様の状況に直面しています。デバッグ後に見つけた

let locationManager = CLLocationManager()

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

どうして?

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

1
Ankur Lahiry

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

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

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    CLLocationManager *locationManager = [[CLLocationManager alloc] init];
    [locationManager startUpdatingLocation];
}
0
Mahdi Nili

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

  • 私のソリューションは、ローカル変数からメンバーインスタンスに変更されました。
  • 原因は、ローカルの変数を含むメソッドが終了した後、local?instanceが無効であったことです(locationManagerの拡張)
  • 私の環境:Xcode9.3.1
 
#import 
 @ interface ViewController()
 
 @ end 
 
 @ implementation ViewController 
 @ synthesize locManager; // after 
-(void)viewDidLoad {
 [super viewDidLoad]; 
 //ビューのロード後に、通常nib。
から追加のセットアップを行います。 
 // MyLocationService * locManager = [[BSNLocationService alloc] init:nil]; // 前。 loc。このメソッドの後にインスタンスが無効になったため、デリゲートは機能しませんでした。
 self-> locManager = [[MyLocationService alloc] init:nil]; // after 
 locManager.startService; 
} 
 
0
user2058374

これは、関数またはメソッド内でクラスまたはラッパーのローカル変数を作成するときに発生します。ロケーションクラス/ラッパーを保持するインスタンス変数を作成します

0
Wasim