locationManager didUpdateLocations在设备上触发两次,在模拟器

时间:2015-11-03 05:33:34

标签: ios swift cllocationmanager

相同的代码,我假设设备实际上由于某种原因实际更新了位置两次,即使我只调用一次startUpdatingLocation()并在didUpdateLocations中运行一些stopUpdatingLocations()

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)
}

在这种情况下,createNewDataPoint被调用两次,创建2个新数据点。它只在模拟器中发生一次,所以我假设它与实际设备和GPS有关,因为模拟器伪造了它的位置。

startUpdatingLocation()只在我的代码中一次,在一个按钮上。基本上,你单击按钮,去go manager.startUpdatingLocations(),didUpdateLocations在模拟器上点击一次,在设备上点击两次(相同的坐标),它会创建2个新的数据点。

提及任何相关内容的唯一其他代码是设置准确性,过滤器,授权请求以及前面提到的startUpdatingLocation()。有什么我可以做的,以确保我没有创建两倍于必要的数据点?

9 个答案:

答案 0 :(得分:15)

可以在任何时候非常频繁地调用位置管理器委托方法。

但是,您可以应用以下算法来保护自己:

  1. 创建全球booldidFindLocation
  2. 致电didFindLocation时,将false设为startUpdatingLocation
  3. 在代理内部回复didUpdateLocations:,如果didFindLocationfalse,请将didFindLocation设置为true,然后致电stopUpdatingLocation
  4. 希望这有帮助。

答案 1 :(得分:8)

最好的方法如下:

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

答案 2 :(得分:6)

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.
}

但不要忘记再次设置委托。

答案 3 :(得分:0)

你不会经常在模拟器上。当你移动很远的地方时,只有你得到didUpdateLocations。只需移动到开放空间,GPS就可以识别您的设备位置,从而获得最佳准确度。

答案 4 :(得分: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
}

当您需要用户的当前位置但不需要保持位置服务运行时,请使用此方法。

答案 5 :(得分:0)

<@> @Zumry Mohamed的解决方案是对的

我尝试这样的代码:

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

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

最后这个委托只被调用一次,我现在明白为什么会出现问题,只是因为经理调用stopUpdatingLocation方法,但系统无法帮助我们使委托无效,所以我们可以收到回调每次由于desiredAccuracy的{​​{1}}和distanceFilter属性设置而导致位置更新,因此最终的解决方案就像@Zumry Mohamed所说的那样,我们可以手动将委托设置为nil我们CLLocationManager。希望它能帮助你理解为什么这可以解决这个问题。

答案 6 :(得分:0)

获得所需的纬度和经度后,只需致电stopUpdatingLocation()并将代表设为nil

在Swift 3中:

locationManager.stopUpdatingLocation() 
locationManager.delegate = nil

在Objective-C中:

[locationManager stopUpdatingLocation]
locationManager.delegate = nil

此处locationManagerCLLocationManager的对象。

答案 7 :(得分:0)

locationManager.startUpdatingLocation()连续获取位置并且didUpdateLocations方法多次调用, 只需在调用locationManager.startUpdatingLocation()之前设置locationManager.distanceFilter值的值。

当我设置200米(你可以根据你的要求改变)工作正常

    locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.distanceFilter = 200
    locationManager.requestWhenInUseAuthorization()
    locationManager.startUpdatingLocation()

答案 8 :(得分:0)

另一种方法是设置时间间隔来打开和关闭委托,以及位置管理器。

var locationManagerUpdate:Bool = false //Global

func scheduledTimerWithTimeInterval(){
    // Scheduling timer to Call the function "updateCounting" with the interval of 10 seconds

        timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(self.updateLocationManager), userInfo: nil, repeats: true)

}
@objc func updateLocationManager() {

    if locationManagerUpdate == false {
        locationManager.delegate = self
        locationManagerUpdate = true
    }

}
extension lm_gest: CLLocationManagerDelegate {

// Handle incoming location events.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {


    if locationManagerUpdate == true {
    manager.stopUpdatingLocation()
    manager.delegate = nil
    }
//your code here...
}