按下按钮后,我有一个CLLocationManager请求位置服务授权,如果用户接受,locationManager将调用startUpdatingLocation()。一旦有更新的位置(即立即调用),我希望ClLocationManagerDelegate调用didUpdateLocations,然后从那里立即调用manager. stopUpdatingLocation()这样我暂时只得到1组坐标,不过,有时候(不一致)我会得到两组坐标,就好像按钮被连续按了两次一样。我知道startUpdatingLocation可能很棘手,因为它可以非常迅速地更新您的位置,直到它被停止,但我似乎无法精确定位在哪里以及如何避免这种情况!我发现许多线程对这个相同的问题,但没有任何工作,为我的具体情况。
我在网上找到了this,并尝试了该线程中的一些东西,但仍然无法修复它。
下面是我的代码:
- getUserLocation()**是按下应用中的按钮时调用的第一个函数。
func getUserLocation() {
self.places.removeAll()
self.placesTableView.reloadData()
LocationService.shared.requestPermissionToAccessLocation()
LocationService.shared.locationUpdated = { [weak self] location in
self?.fetchPlaces(location: location)
}
self.view.addSubview(placesTableView)
placesTableView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate(
[
placesTableView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 200),
placesTableView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 150),
placesTableView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -10),
placesTableView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -130),
]
)
}
private func fetchPlaces(location: CLLocationCoordinate2D) {
let searchSpan = MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)
let searchRegion = MKCoordinateRegion(center: location, span: searchSpan)
let searchRequest = MKLocalSearch.Request()
searchRequest.region = searchRegion
searchRequest.resultTypes = .pointOfInterest
searchRequest.naturalLanguageQuery = "bar"
let search = MKLocalSearch(request: searchRequest)
search.start { response, error in
guard let mapItems = response?.mapItems else {
return
}
DispatchQueue.main.async { [weak self] in
for item: MKMapItem in mapItems {
let placeMark = item.placemark as CLPlacemark
let completeBusinessString = String(format: "%@\n%@ %@\n%@, %@ %@", placeMark.name!, placeMark.subThoroughfare!, placeMark.thoroughfare!, placeMark.locality!, placeMark.administrativeArea!, placeMark.postalCode!)
self?.places.append(completeBusinessString)
}
self?.placesTableView.reloadData()
}
}
}
- 位置服务单例类**
class LocationService: NSObject {
static let shared = LocationService()
lazy var locationManager: CLLocationManager = {
let manager = CLLocationManager()
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.delegate = self
return manager
}()
var locationUpdated: ((CLLocationCoordinate2D) -> Void)?
override private init() {
super.init()
}
func requestPermissionToAccessLocation() {
switch locationManager.authorizationStatus {
case .notDetermined:
locationManager.requestWhenInUseAuthorization()
case .restricted:
locationManager.requestWhenInUseAuthorization()
case .denied:
break
case .authorizedAlways:
locationManager.startUpdatingLocation()
case .authorizedWhenInUse:
locationManager.startUpdatingLocation()
default:
break
}
}
}
extension LocationService: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
manager.stopUpdatingLocation()
if let location = locations.last?.coordinate {
print(location)
locationUpdated?(location)
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error.localizedDescription)
}
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
switch manager.authorizationStatus {
case .authorizedAlways:
manager.startUpdatingLocation()
case .authorizedWhenInUse:
manager.startUpdatingLocation()
default:
break
}
}
}
1条答案
按热度按时间pbossiut1#
如果目标只是得到一个告诉你位置的值,那么你就做错了;使用
requestLocation
。