2013-04-18 109 views
5

我開始更新當前位置,當視圖確實出現時,並且只要調用locationManager:didUpdateLocations:就停止更新位置。但爲什麼總是多次調用locationManager:didUpdateLocations:?我錯過了什麼?locationManager:didUpdateLocations:總是被多次調用

#import "ViewController.h" 

@interface ViewController(){ 
    CLLocationManager *locationManager; // location manager for current location 
} 
@end 

@implementation ViewController 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
} 

- (void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 
    [self startUpdatingCurrentLocation]; 
} 

- (void)startUpdatingCurrentLocation 
{ 
    if (!locationManager) 
    { 
     locationManager = [[CLLocationManager alloc] init]; 
     [locationManager setDelegate:self]; 
     locationManager.distanceFilter = 10.0f; // we don't need to be any more accurate than 10m 
    } 
    [locationManager startUpdatingLocation]; 
} 

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{ 
    [locationManager stopUpdatingLocation]; 
} 
@end 
+0

http://stackoverflow.com/questions/22292835/how-to-stop -dultiple-times-method-calling-of-didupdatelocations-in-ios – Sanju 2016-05-27 10:02:25

回答

7

可能取決於您設置到locationManager的準確性。您有三種本地化的Cell Radio,WiFi Map,GPS。如果您將精度設置得最好,位置管理器將繼續檢查您的位置,如果精度更高的位置超出距離過濾器的範圍,委託方法將再次被調用。

+0

why [locationManager stopUpdatingLocat離子]不能立即停止位置更新? – 2013-04-18 07:43:04

+1

可能不是,因爲位置隊列來自硬件緩衝區,但是如果問題存在,那麼只需在停止並檢查之前添加一個靜態BOOL即可。如果BOOL說你已經停止從該方法返回。 – Andrea 2013-04-18 07:59:18

+0

是的,這是一個解決方案。 – 2013-04-18 08:01:17

3

SWIFT版本

我犯了一個輔助類爲HelperLocationManager,並增加了notification- observer模式

import UIKit 
import CoreLocation 



class HelperLocationManager: NSObject { 

    var locationManager = CLLocationManager() 
    static let sharedInstance = HelperLocationManager() 
    var currentLocation :CLLocation? 
    var notGotUserLocation = true 

    override init() { 

     super.init() 

     var code = CLLocationManager.authorizationStatus() 

     if code == CLAuthorizationStatus.NotDetermined { 

      locationManager.requestAlwaysAuthorization() 
      locationManager.requestWhenInUseAuthorization() 

     } 
     locationManager.requestAlwaysAuthorization() 
     locationManager.requestWhenInUseAuthorization() 
     locationManager.delegate = self 
     locationManager.distanceFilter = 100; 

    } 


} 


extension HelperLocationManager: CLLocationManagerDelegate{ 


    func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) { 

      var locValue = locations.last as! CLLocation 
      println(locValue) 
      self.currentLocation = locValue 
      NSNotificationCenter.defaultCenter().postNotificationName("sendCurrentAddressToViewController", object:self.currentLocation) 
      notGotUserLocation = false 


    } 

    func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) { 

     println("Your error is ", error.localizedDescription) 

    } 


} 

現在,如果你Viewcontroller類需要的位置,然後放在一個觀察者有

var helperLocation:HelperLocationManager? 

viewDidLoad as

 override func viewDidLoad() { 

     helperLocation = HelperLocationManager() 
     NSNotificationCenter.defaultCenter().addObserver(self, selector: "getCurrentAddressToViewController:", name: "sendCurrentAddressToViewController", object: nil) 

    } 

//和觀察者

func getCurrentAddressToViewController(notification: NSNotification) { 

     currentLocation = notification.object as? CLLocation 
     NSNotificationCenter.defaultCenter().removeObserver(self, name: "sendCurrentAddressToViewController", object: nil) 

    } 

//雖然didUpdateLocation被多次調用你只能得到因爲刪除observer你的位置之後的一個時間位置。

編輯:我refractored這個輔助類,這樣你不需要添加notificationobserver模式

class HelperLocationManager: NSObject { 

    private lazy var locationManager = CLLocationManager() 
    static let sharedInstance = HelperLocationManager() 
    var currentLocation :CLLocation? 

    override init() { 

     super.init() 
     locationManager.desiredAccuracy = kCLLocationAccuracyBest 
     locationManager.delegate = self 
    } 
} 

extension HelperLocationManager: CLLocationManagerDelegate{ 

    func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) { 

     switch status { 

     case CLAuthorizationStatus.NotDetermined: 

      locationManager.requestWhenInUseAuthorization() 


     case CLAuthorizationStatus.Restricted: 

      PrinterHelper.messagePrinter("Restricted Access to location") 

     case CLAuthorizationStatus.Denied: 

      PrinterHelper.messagePrinter("User denied access to location") 

     case CLAuthorizationStatus.AuthorizedWhenInUse: 

      if #available(iOS 9.0, *) { 

       locationManager.requestLocation() 

      } else { 

       locationManager.startUpdatingLocation() 
      } 

     default: 

      PrinterHelper.messagePrinter("default authorization") 

     } 
    } 

    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 

     let locValue = locations.last 
     HelperLocationManager.sharedInstance.currentLocation = locValue 
     locationManager.stopUpdatingLocation() 

    } 

    func locationManager(manager: CLLocationManager, didFailWithError error: NSError) { 

     PrinterHelper.errorPrinter(error.localizedDescription) 

    } 
} 

視圖控制器,你需要得到用戶許可

var helperLocationManager:HelperLocationManager? 
viewDidLoad

 override func viewDidLoad() { 

     helperLocationManager = HelperLocationManager.sharedInstance 


    } 

而得到的位置,你需要調用singleton屬性currentLocation作爲

if let userCurentLoc = HelperLocationManager.sharedInstance.currentLocation{ 

      //userCurrentLoc is the user Location 

     } 
0

以補充阿尼什的答案,如果你想知道當你的助手類沒有叫位置更新(即當您已關閉您的位置服務),則可以使用locationManager:didChangeAuthorizationStatus:方法管理這一點,如果不允許你的位置,你可以調用另一個notification- observer

func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) { 
    var shouldIAllow = false 

    switch status { 
    case CLAuthorizationStatus.Restricted: 
     locationStatus = "Restricted Access to location" 
    case CLAuthorizationStatus.Denied: 
     locationStatus = "User denied access to location" 
    case CLAuthorizationStatus.NotDetermined: 
     locationStatus = "Status not determined" 
    default: 
     locationStatus = "Allowed to location Access" 
     shouldIAllow = true 
    } 

    if (shouldIAllow == true) { 
     print("Location to Allowed") 
     // Start location services 
     locationManager!.startUpdatingLocation() 
    } else { 
     print("Denied access: \(locationStatus)") 
     NSNotificationCenter.defaultCenter().postNotificationName("deniedLocation", object:locationStatus) 
    } 
}