私のアプリはユーザーの位置を取得し、座標を取得し、目的地または起点までの距離を提供します。これらの可能な宛先はすべてテーブルビューに表示されるため、テーブルにデータを入力すると同時にユーザーの座標を取得しています。唯一のことは、ユーザーの場所を尋ねるアラートビューが表示され、すぐに消えてクリックできないことです!
アプリが最初に読み込まれたときにこのアラートを手動で表示する方法はありますか?アプリがロードされたときにユーザーの現在地を取得して、アラートを強制的に表示しようとしましたが、うまくいきませんでした。
追跡するのは困難ですが、これに対する解決策は非常に簡単です。
多くの試行錯誤を通して、アプリ内の位置情報サービスに初めてアクセスしようとすると位置情報アクセスダイアログが表示されますが、CLLocationManager
オブジェクトは、ユーザーがダイアログに応答する前に解放されます。
CLLocationManager
メソッドでviewDidLoad
インスタンスを作成していました。これはメソッドのローカルインスタンスであるため、インスタンスはメソッドの実行が完了した後にARCによって解放されました。インスタンスがリリースされるとすぐに、ダイアログは消えました。解決策はかなり簡単でした。 CLLocationManager
インスタンスをメソッドレベルの変数からクラスレベルのインスタンス変数に変更します。これで、クラスがアンロードされると、CLLocationManager
インスタンスのみが解放されます。
同じ症状、異なる原因:startUpdatingLocation
を連続して複数回呼び出さないでください。
誤ってコードが意図せずにstartUpdatingLocation
を2回連続して呼び出すように構成しましたが、これは明らかに悪いことです。また、ネットワークリクエストの結果が出るまで更新を開始するのを待っていたため、キューの選択と関係があるかもしれませんが、それを修正するためにGCDマジックを実行する必要はありませんでした。開始を繰り返さなかった。
誰かが私の痛みから利益を得ることができることを願っています。 :)
これは非常に遅い返信であることを知っています。しかし、それは誰かを助けるかもしれません。私も同じ問題に直面し、問題を特定するのに1時間かかりました。最初は私のコードはこんな感じでした。
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
[locationManager startUpdatingLocation];
CLLocation *location = locationManager.location;
//my stuff with the location
[locationManager release];
これで、ロケーションアラートはすぐに消えました。最後の行のコメントを外すと、正常に機能しています。
// [locationManager release];
私は同じ問題に陥ります(少なくとも症状によって)。私の場合、問題は- (void)applicationWillResignActive:(UIApplication *)application;
メソッドにあり、そこではバックグラウンド移行の準備の一環としてCLLocationManager
インスタンスをリリースしていました。削除して- (void)applicationDidEnterBackground:(UIApplication *)application;
のみに残した場合、問題はなくなりました。
注意が必要なのは、コアロケーションアラートがアプリケーションをフォアグラウンドにある間中断することです。
それがあなたを助けることを願っています、私がそのろくでなしを見つけるのに多くの時間がかかりました:)
私もこの問題に遭遇しましたが、私の場合の解決策は、受け入れられた答えとはまったく異なることが判明しました。
私のアプリでは、stopUpdatingLocation
からapplicationWillResignActive
を呼び出していました。許可ダイアログが表示されたときにapplicationWillResignActive
が呼び出されるため、これは問題でした。これはstopUpdatingLocation
の直後にstartUpdatingLocation
を引き起こしていたため、ダイアログはすぐに消えます。
解決策は、代わりにstopUpdatingLocation
からapplicationDidEnterBackground
を呼び出すことです。
必ずプライバシー行(alwaysとwhenInUse)の両方を追加してください_.plist
_ファイルを作成し、CoreLocation
Frameworkをプロジェクトに追加します
変更すると、場所の許可ダイアログが正しく表示されます。
_locationManager.requestAlwaysAuthorization()
_
で:
_locationManager.requestWhenInUseAuthorization()
_
PS .:試しました[〜#〜] all [〜#〜]アドバイスとすべて失敗(viewDidLoad
、var
locationManagerのlet
の代わりに、リクエスト後にstartUpdatingLocation()
を開始しないでください。これはバグだと思うので、できるだけ早く解決することを願っています。
これは、iOSシミュレーターの使用中に起こっていました。 Run Schemeが場所をシミュレートしているために発生していると判断しました。これは、起動時にlocationManager.startUpdatingLocation()
を呼び出すのと同じ効果があるため、ダイアログを閉じていたと思います。
[スキームの編集]ダイアログの[ロケーションシミュレーションを許可する]チェックボックスをオフにすると、問題が修正されました。希望どおりに機能し、許可が設定されたら、ロケーションシミュレーションを再度有効にできます。それ以降、シミュレーターは正常に動作します。
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
}
}
私は同様の状況に直面しています。デバッグ後に見つけた
let locationManager = CLLocationManager()
メソッドスコープで呼び出されますが、グローバルに呼び出す必要があります。
どうして?
一言で言えば、locationManagerはメソッドが返された後に解放されています。ただし、ユーザーが許可または拒否するまでリリースしないでください
ほとんどの場合、locationManager変数をグローバルオブジェクトとして定義します。
@interface ViewController : UIViewController
{
CLLocationManager *locationManager;
}
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
[locationManager startUpdatingLocation];
}
私はあなたの同じ状況に会いました。
#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; }
これは、関数またはメソッド内でクラスまたはラッパーのローカル変数を作成するときに発生します。ロケーションクラス/ラッパーを保持するインスタンス変数を作成します