2015-11-03 9 views
8

同じコードです。私はstartUpdatingLocation()を一度だけ呼び出してstopUpdatingLocations()を実行しても、この場合locationManager didUpdateLocationsは、デバイス上で2回、シミュレータで1回だけ発生します。

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 
    manager.stopUpdatingLocation() 
    let loc: CLLocation = locations[locations.count - 1] 
    let id = 0 
    let type = 0 
    let number = 0 

    createNewDataPoint(id, loc: loc, type: type, number: number) 
} 

didUpdateLocationsの内側に、createNewDataPointは、2つの新しいデータポイントを作成し、二回呼び出されます。それはシミュレータで一度しか起こらないので、シミュレータがその位置を偽装するので、実際のデバイスとGPSと何か関係があると仮定しています。

startUpdatingLocation()は、コード上でボタン上に1回だけ表示されます。基本的には、ボタンをクリックし、manager.startUpdatingLocations()に移動し、didUpdateLocationsがシミュレータで一度ヒットし、デバイス上で2回(同一の座標)、2つの新しいデータポイントが作成されます。

他のコードは、精度、フィルタ、承認リクエスト、前述のstartUpdatingLocation()の設定だけです。必要な倍のデータポイントを作成していないことを確認するためにできることはありますか?

+0

細かい作業(あなたはあなたの条件として変更することができます)200メートルをされているように、私はあなたが1 'didUpdateLocations'を得ればそれをオン、フラグを作成することができると思います。私は問題は、 'CLLocationManager'が非常に速く更新され、' stopUpdatingLocation'が完了するまでに時間がかかることです。 – anhtu

+1

以前のバージョンで提案されているテクニックの1つを使用する必要がありますが、ios9をチェックし、その場合は 'requestLocation'を使用することをお勧めします。 – Paulw11

答えて

11

ロケーションマネージャの委任方法は、非常に頻繁に、いつでも呼び出すことができます。

あなたはしかし、自分を守るために、以下のアルゴリズムを適用することができる:

  1. は、グローバルbooldidFindLocationを言う作成します。
  2. に電話すると、didFindLocationfalseに設定されます。バックデリゲート呼び出しdidUpdateLocations:インサイド
  3. didFindLocationは、falsetruedidFindLocationを設定し、stopUpdatingLocationを呼び出す場合。

これが役に立ちます。

+0

単純な解決策です。私のコードでは問題ではないと聞いてよかったですが、場所がすばやく更新されて2回発射されてから止めることができただけです。私はまた、数回、それが3回呼ばれたことに気づいた。 – sdouble

+0

stopUpdateLocaitonが呼び出される前にdelegate didUpdateLocationが再度呼び出される可能性はありませんか?私はここで間違っているかもしれないが、確かに確認したかった。または、前のデリゲートがまだ実行されていない限り、システムはデリゲートを呼び出さないでしょうか?私がばかげている場合は、私はかなりiOSを新しくしています。デリゲートにロックを追加するのは良い設計ですか? – user3508953

+0

ベストソリューション!デリゲートをnilに設定するのは危険です。デリゲートのメソッド(locationManager:didChangeAuthorizationStatus:など)を追跡することが重要だと思います。 –

0

あなたは頻繁にシミュレータを使用することはありません。あなたが遠くに移動するときにはデバイス上でdidUpdateLocationsが得られます。オープンスペース内を移動するだけで、GPSがデバイスの場所を特定できるので、最高の精度が得られます。

7

最良の方法は、以下のようにしてくださいです:

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 
    manager.stopUpdatingLocation() 
    manager.delegate = nil 
} 
+0

この一番簡単な回答のおかげで –

5

のiOS 10.0+のためのベストソリューション

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations { 
    [locationManager stopUpdatingLocation]; // stop location manager 
    locationManager.delegate = nil; 
    //Your logics... 
    //This will be called only one time now. 
} 

しかし、再びデリゲートを設定することを忘れないでください。

+0

デリゲートをnilに設定することが最も重要な部分です! –

0

代わりに/開始位置更新を終了し、nilにデリゲートを設定するので、アプリケーションがユーザーの位置に簡単な修正を必要とする場合に理想的ですrequestLocationと呼ばれる方法があります:

ドキュメントから:

override func viewDidLoad() { 
    // Create a location manager object 
    self.locationManager = CLLocationManager() 

    // Set the delegate 
    self.locationManager.delegate = self 
} 

func getQuickLocationUpdate() { 
    // Request location authorization 
    self.locationManager.requestWhenInUseAuthorization() 

    // Request a location update 
    self.locationManager.requestLocation() 
    // Note: requestLocation may timeout and produce an error if authorization has not yet been granted by the user 
} 

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 
    // Process the received location update 
} 

このメソッドは、ユーザーの現在の位置は必要ですが、位置情報サービスを実行したままにする必要がない場合に使用します。

0

@Zumryモハメドのソリューションは、私がこのようなコードを試してみてください

右です:最後に、このデリゲートは、一度だけ呼び出され

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { 

    [self.locationManager stopUpdatingLocation]; 
    self.locationManager.delegate = nil; 
    self.locationManager = nil; 
} 

問題が発生した理由を、私は今理解し、単にマネージャので、 stopUpdatingLocationメソッドを呼び出しても、代理人を無効にすることはできません。desiredAccuracydistanceFilterのプロパティ設定がCLLocationManagerのため、場所の更新が行われるたびにコールバックを受け取ることができるので、最終的な解決策は@Zumry Mohamed言った、我々は手動で設定することができますd私たちがstopUpdateLocationの時にエレガントから無し。これがなぜ問題を解決できるのかがどうなるのか理解するのを助けてくれることを願っています。

0

希望の緯度と経度を取得したら、stopUpdatingLocation()に電話して、代理人をnilに設定してください。スイフト3において

:Objective-Cでは

locationManager.stopUpdatingLocation() 
locationManager.delegate = nil 

ここ
[locationManager stopUpdatingLocation] 
locationManager.delegate = nil 

locationManagerCLLocationManagerの目的です。

+0

コードを書式設定してください。 –

0

locationManager.startUpdatingLocation()を連続的位置を取得し、didUpdateLocations方法は ちょうどlocationManager.startUpdatingLocation()を呼び出す前にlocationManager.distanceFilter値の値を設定し、いくつかの回を呼び出します。

私は

locationManager = CLLocationManager() 
    locationManager.delegate = self 
    locationManager.desiredAccuracy = kCLLocationAccuracyBest 
    locationManager.distanceFilter = 200 
    locationManager.requestWhenInUseAuthorization() 
    locationManager.startUpdatingLocation() 
関連する問題