使用操作获取 CLLocation 数据
Get CLLocation data using an Operation
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 属性 并在我调用 (_:didUpdateLocations) 中的 handler(location) 后手动将其设置为 true,但这是只读的 属性。这个 link 提供了一种方法来做到这一点,但我不确定实现。 如何在将位置传递给处理程序之前阻止操作完成?。谢谢!
两个严重的问题:
manager
在 main()
中本地声明并在 main()
退出后销毁。
替换
private var manager: CLLocationManager?
和
private let manager = CLLocationManager()
并删除局部变量
let manager = CLLocationManager()
在 main()
中。我什至更喜欢 lazy
属性。
您必须按照描述使用异步 Operation
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 属性 并在我调用 (_:didUpdateLocations) 中的 handler(location) 后手动将其设置为 true,但这是只读的 属性。这个 link 提供了一种方法来做到这一点,但我不确定实现。 如何在将位置传递给处理程序之前阻止操作完成?。谢谢!
两个严重的问题:
manager
在main()
中本地声明并在main()
退出后销毁。替换
private var manager: CLLocationManager?
和
private let manager = CLLocationManager()
并删除局部变量
let manager = CLLocationManager()
在
main()
中。我什至更喜欢lazy
属性。您必须按照描述使用异步
Operation