I'm doing a iOS application relate user's location.
I setup CLLocationManager and it works good, but after I call stopUpdatingLocation() on CLLocationManager, the delegation method "didUpdateLocations" still get called couple of times. And this is not always happens.
Is this because the latency between the call of stopUpdatingLocation() and the locationManager really get stopped?
This is how my CLLocationManager got setup:
final class LocationController: NSObject {
typealias Action = (CLLocation) -> ()
static let shareInstance = LocationController()
private let locationManager = CLLocationManager()
private var location: CLLocation?
private var action: Action?
private var timer: NSTimer?
private override init () {
super.init()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.activityType = .Fitness
}
}
This is my delegation method:
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let newLocation = locations.last!
let accuracy = newLocation.horizontalAccuracy
// horizontalAccuracy less than 0 is invalid result, ignore it
guard accuracy >= 0 else { return }
// ignore the result that accuracy less than desiredAccuracy
guard accuracy <= locationManager.desiredAccuracy else { return }
// accept the result
self.location = newLocation
// stop locating
self.stopLocationManager()
}
This is how I stop locationManager:
func stopLocationManager() {
self.locationManager.stopUpdatingLocation()
print("the location manager should be stopped!!!!!!!!!!!")
if let timer = self.timer {
timer.invalidate()
}
guard let action = self.action else { return }
if let location = self.location {
action(location)
} else {
action(TomoConst.Geo.CLLocationTokyo)
}
self.action = nil
self.location = nil
}
And this is how I use my LocationManager:
func doActionWithLocation(action: Action) {
self.action = action
guard self.determineStatus() else { return }
self.timer = NSTimer.scheduledTimerWithTimeInterval(30, target: self, selector: Selector("stopLocationManager"), userInfo: nil, repeats: false)
self.locationManager.startUpdatingLocation()
print("the location manager started!!!!!!!!!!!")
}
As the result, I saw "the location manager started!" for once, and then saw "the location manager should be stopped!" for multiple times. I think the stop message should be printed just for one time. and I debugged for a very long time with no luck.
please anybody tell me why....
thanks in advance.
BTW, if I setup everything in a extreme-simple style, LocationManager got stopped correctly:
let locman = CLLocationManager()
var count = 1
override func viewDidLoad() {
super.viewDidLoad()
locman.delegate = self
locman.desiredAccuracy = kCLLocationAccuracyHundredMeters
locman.activityType = .Fitness
locman.requestWhenInUseAuthorization()
locman.startUpdatingLocation()
print("start")
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("\(count) \(locations.last)")
if self.count == 5 {
locman.stopUpdatingLocation()
}
count++
}
the code above print message 5 times, and seems no further didUpdateLocations get called.