import Foundation
import CoreLocation
class LocationOperation: Operation, CLLocationManagerDelegate {
// MARK: Properties
private var manager: CLLocationManager?
private let handler: (CLLocation) -> Void
// MARK: Initialization
init(locationHandler: @escaping (CLLocation) -> Void) {
self.handler = locationHandler
super.init()
}
// MARK: Main
override func main() {
DispatchQueue.main.async {
let manager = CLLocationManager()
manager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
manager.delegate = self
manager.startUpdatingLocation()
}
}
override func cancel() {
DispatchQueue.main.async {
self.stopLocationUpdates()
super.cancel()
}
}
private func stopLocationUpdates() {
manager?.stopUpdatingLocation()
manager = nil
}
// MARK: CLLocationManagerDelegate
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last,
location.horizontalAccuracy <= manager.desiredAccuracy else {
return
}
stopLocationUpdates()
handler(location)
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
stopLocationUpdates()
print("Failure to find location") // handle this eventually
self.cancel()
}
}
main завершает выполнение до того, как CLLocationManager получит шанс получить местоположение и передать его переданному обработчику.Первой попыткой было переопределить свойство isExecuting и вручную установить для него значение true после вызова обработчика (location) в (_: didUpdateLocations), но это свойство только для чтения.Эта ссылка предоставила способ сделать это, но я не был уверен в реализации. Как остановить остановку операции до того, как она передаст местоположение обработчику? .Спасибо!