【问题标题】:Get CLLocation data using an Operation使用操作获取 CLLocation 数据
【发布时间】:2018-09-11 18:59:36
【问题描述】:
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 提供了一种方法来做到这一点,但我不确定实现。 如何在操作将位置传递给处理程序之前阻止操作完成? .谢谢!

【问题讨论】:

    标签: swift cllocationmanager operation


    【解决方案1】:

    两个严重的问题:

    1. managermain() 中本地声明,并在main() 退出后销毁。

      替换

      private var manager: CLLocationManager?
      

      private let manager = CLLocationManager()
      

      并删除局部变量

      let manager = CLLocationManager()

      main()。我什至更喜欢lazy 属性。

    2. 您必须使用异步 Operation,如 here 所述

    【讨论】:

    • 好收获!我不小心留下了我在 main() 中声明管理器的代码。链接中的解决方案效果很好。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2014-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-19
    • 2017-02-28
    • 2018-01-23
    相关资源
    最近更新 更多