在下面的代码中,我正在使用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.")
}
})
}
答案 0 :(得分:1)
您的代码存在的问题是,在您进行locationManager(_:didUpdateLocations:)
时,可能已经多次调用self.locationManager.stopUpdatingLocation()
。要解决这个问题:
var didFindZipCode: Bool = false
。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
开头。