SWIFT - LocationManager循环多次? [英] SWIFT - LocationManager looping through multiple times?
问题描述
我有一个locationManager功能来获取用户当前位置并发布城市和州的名称。我有一个打印声明,所以我可以在我的控制台检查一切是否正常工作......事实确实如此。但是,它打印城市位置3次。这实际上在我的实际应用中引起了一个问题,但这超出了这个问题的范围。
I have a locationManager function to grab the users current location and posting the name of the city and state. I have a print statement so I can check in my console if everything is working properly...and it is. However, it prints the city location 3 times. This actually causes an issue in my actual app but thats beyond the point of this question.
我的功能如下:
var usersLocation: String!
var locationManager: CLLocationManager!
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation: CLLocation = locations[0]
CLGeocoder().reverseGeocodeLocation(userLocation) { (placemarks, error) -> Void in
if error != nil {
print(error)
} else {
let p = placemarks?.first // ".first" returns the first element in the collection, or nil if its empty
// this code above will equal the first element in the placemarks array
let city = p?.locality != nil ? p?.locality : ""
let state = p?.administrativeArea != nil ? p?.administrativeArea : ""
self.navigationBar.title = ("\(city!), \(state!)")
self.usersLocation = ("\(city!), \(state!)")
self.locationManager.stopUpdatingLocation()
print(self.usersLocation)
self.refreshPosts()
}
}
}
所以在我的打印(self.usersLocation)中它会打印出来我的控制台三次。这是正常的吗?
So in my print(self.usersLocation) it will print in my console three times. Is this normal?
更新显示视图
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 250.0
}
推荐答案
我首先建议一些事情:
-
致电
stopUpdatingLocation
在执行reverseGeocodeLocation
之前。
您正在调用 stopUpdatingLocation
在 reverseGeocodeLocation
完成处理程序关闭内。问题是它以异步方式运行,因此 didUpdateLocations
可能会在此期间收到其他位置更新。通常,当您第一次启动位置服务时,您将获得许多更新,通常会提高准确性(例如 horizontalAccuracy
越来越小的值)。如果在启动异步地理编码请求之前关闭位置服务,则可以最大限度地减少此问题。
You are calling stopUpdatingLocation
inside the reverseGeocodeLocation
completion handler closure. The problem is that this runs asynchronously, and thus didUpdateLocations
may receive additional location updates in the intervening period. And often, when you first start location services, you'll get a number of updates, often with increasing accuracy (e.g. horizontalAccuracy
values that are smaller and smaller). If you turn off location services before initiating asynchronous geocode request, you'll minimize this issue.
您还可以添加添加 distanceFilter 在
viewDidLoad
中,这将最大程度地减少对委托方法的冗余调用:
You can also add add a distanceFilter
in viewDidLoad
, which will minimize redundant calls to the delegate method:
locationManager.distanceFilter = 1000
您可以使用自己的州检查反向地理编码过程是否已启动的变量。例如:
You can use your own state variable that checks to see if the reverse geocode process has been initiated. For example:
private var didPerformGeocode = false
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// if we don't have a valid location, exit
guard let location = locations.first where location.horizontalAccuracy >= 0 else { return }
// or if we have already searched, return
guard !didPerformGeocode else { return }
// otherwise, update state variable, stop location services and start geocode
didPerformGeocode = true
locationManager.stopUpdatingLocation()
CLGeocoder().reverseGeocodeLocation(location) { placemarks, error in
let placemark = placemarks?.first
// if there's an error or no placemark, then exit
guard error == nil && placemark != nil else {
print(error)
return
}
let city = placemark?.locality ?? ""
let state = placemark?.administrativeArea ?? ""
self.navigationBar.title = ("\(city), \(state)")
self.usersLocation = ("\(city), \(state)")
print(self.usersLocation)
self.refreshPosts()
}
}
这篇关于SWIFT - LocationManager循环多次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!