使用LocationManager时,最小化对我的服务器的HTTP请求

时间:2018-12-23 14:32:36

标签: swift cllocationmanager locationmanager

在下面的代码中,我正在使用LocationManager获取用户的当前zipCode,然后向自己的服务器发出HTTP请求以获取基于用户zipCode的一些数据。我的问题是,下面的代码每次调用locationManager时都会发出一个HTTP请求,通常每次调用三次。理想情况下,我只想在找到最后一个地标后发出HTTP请求。

如何最小化对自己服务器的HTTP请求?

override func viewDidLoad() {
    super.viewDidLoad()
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestWhenInUseAuthorization()
    locationManager.startUpdatingLocation()
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    CLGeocoder().reverseGeocodeLocation(manager.location!, completionHandler: {(placemarks, error)-> Void in
        if error != nil {
            //AlertView to show the ERROR message
        }
        if placemarks!.count > 0 {
            let placemark = placemarks![0]
            var zipCode = placemark.postalCode ?? ""
            makeHTTPRequest(zipCode) // this is called 3 times
            self.locationManager.stopUpdatingLocation()

        }else{
            print("No placemarks found.")
        }
    })
}

2 个答案:

答案 0 :(得分:1)

您的代码存在的问题是,在您进行locationManager(_:didUpdateLocations:)时,可能已经多次调用self.locationManager.stopUpdatingLocation()。要解决这个问题:

  • 定义全局变量var didFindZipCode: Bool = false
  • 在要检查地标数量的if块的开头添加guard didFindZipCode == false else { return }
  • 在保护声明之后立即设置didFindZipCode = true

只要记得要重新开始更新位置,就将didFindZipCode设置为false

答案 1 :(得分:1)

问题在于您的CLGeocoder方法异步返回,并且在返回值时,您的位置管理器已经触发了多次。因此,只需在位置管理员的首次呼叫后停止更新位置,然后进行异步工作即可。

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

    guard let location = locations.last else {
        return
    }

    // handle async work
    CLGeocoder().reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in

        if let error = error {
            // alert with error
        } else if let placemarks = placemarks,
            placemarks.count > 0 {
            let placemark = placemarks[0]
            var zipCode = placemark.postalCode ?? ""
            makeHTTPRequest(zipCode)
        } else {
            print("No placemarks found.")
        }

    })

    locationManager.stopUpdatingLocation() // stop updating

}

顺便说一句,链接您的if-else语句也是一种好习惯。如果以if开头,则几乎应始终以else开头,而不是以新的if开头。