swift 为什么我的CLLocationManager有时会在调用startUpdatingLocation后更新位置两次

k7fdbhmy  于 2023-01-01  发布在  Swift
关注(0)|答案(1)|浏览(178)

按下按钮后,我有一个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
        }
    }

}
pbossiut

pbossiut1#

如果目标只是得到一个告诉你位置的值,那么你就做错了;使用requestLocation

相关问题