Get CLLocation data using an Operation
Clash Royale CLAN TAG#URR8PPP
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 finishes executing before CLLocationManager gets a chance to get the location and pass that to the passed in handler. The first attempted solution was to override the isExecuting property and manually set it to true after I call handler(location) in (_:didUpdateLocations) but that's a read only property. This link provided a way to do that, but I wasn't sure about the implementation. How do I stop the operation from finishing before it passes the location to the handler? . Thanks!
1 Answer
1
Two serious issues:
manager
is declared locally in main()
and get destroyed after main()
exits.
manager
main()
main()
Replace
private var manager: CLLocationManager?
with
private let manager = CLLocationManager()
and delete the local variable
let manager = CLLocationManager()
let manager = CLLocationManager()
in main()
. I'd even prefer a lazy
property.
main()
lazy
You have to use an asynchronous Operation
as described here
Operation
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Good catch! I accidentally left the code where I declared manager in main(). The solution in the link works nicely. Thanks.
– Nick Rizzo
Sep 12 at 0:56