I'm working with CLLocationManager class. I want to get location updates periodically. I had found two methods to get location in didUpdateLocations method, that are startUpdatingLocation() and startMonitoringSignificantLocationChanges(). If I have to track location updates in foreground mode also then which method should I use?
The most important difference between the 2 is this:
startMonitoringSignificantLocationChanges: it does not rely on the value in the distanceFilter property to generate events. The receiver generates update events only when a significant change in the user’s location is detected
startUpdatingLocation : the receiver generates update events primarily when the value in the distanceFilter property is exceeded
So, if you want more precision, go for startUpdatingLocation, at the expense of more battery consumption, but more precision of the location. It really depends on your goal, you should evaluate the tradeoff.
startMonitoringSignificantLocationChanges initiates the delivery of location events asynchronously, returning shortly after you call it. Location events are delivered to your delegate’s locationManager:didUpdateLocations: method. The first event to be delivered is usually the most recently cached location event (if any) but may be a newer event in some circumstances. After returning a current location fix, the receiver generates update events only when a significant change in the user’s location is detected. Apps can expect a notification as soon as the device moves 500 meters or more from its previous notification.
To sum up startMonitoringSignificantLocationChanges will provide you with location only when location changes by some significant amount which is roughly around 500 meters or after some fixed time say 5 minutes. Where as startUpdatingLocation will provide you with location based on distanceFilter property set. Default value of distanceFilter is kCLDistanceFilterNone which reports all the movements.
startUpdatingLocation returns immediately. Calling this method causes the location manager to obtain an initial location fix (which may take several seconds) and notify your delegate by calling its locationManager:didUpdateLocations: method. After that, the receiver generates update events primarily when the value in the distanceFilter property is exceeded. Updates may be delivered in other situations though. For example, the receiver may send another notification if the hardware gathers a more accurate location reading.
Related
to retrieve location of the user when the app is in the background i first do startMonitoringSignificantLocationChanges then when DidUpdateLocations is fired i do with a second CLLocationManager startUpdatingLocation to retrieve the exact geoposition (with an accuracy on 100m)
The problem is that the doc say:
Calling this method causes the location manager to obtain an initial
location fix (which may take several seconds). After that, the receiver generates update events primarily when the value in the distanceFilter property is exceeded.
So as i understand the first DidUpdateLocations will be called with a fix not really accurate, and with time other DidUpdateLocations will be called with more accurate location.
Now the problem is, when (and how?) did i need to stop the startUpdatingLocation ? i m in the background so i can't use any timer or think like this
Since you require a 100m accuracy, you can simply check the location horizontal accuracy property. If the condition is fulfilled you can stop the core location manager otherwise you keep tracking.
Be aware that usually the callback of significant monitoring changes keeps your app alive for a minimum amount of time.
At wake-up time, the app is put into the background and you are given
a small amount of time (around 10 seconds) to manually restart
location services and process the location data. (You must manually
restart location services in the background before any pending
location updates can be delivered, as described in Knowing When to
Start Location Services.) Because your app is in the background, it
must do minimal work and avoid any tasks (such as querying the
network) that might prevent it from returning before the allocated
time expires. If it does not, your app will be terminated. If an iOS
app needs more time to process the location data, it can request more
background execution time using the
beginBackgroundTaskWithName:expirationHandler: method of the
UIApplication class.
In Significant change location service, I've used the method "startMonitoringSignificantLocationChanges" but it returns cached Location only, it doesn't return updated location information.
I've used Swift language.
Assuming you are keeping a strong reference to your location manager object, please ensure you are calling locationManager.requestAlwaysAuthorization() for startMonitoringSignificantLocationChanges to function well.
EDIT:
From Apple Documentation:
Regardless of which location service you use, location data is
reported to your app via the location manager’s associated delegate
object. Because it can take several seconds to return an initial
location, the location manager typically delivers the previously
cached location data immediately and then delivers more up-to-date
location data as it becomes available. Therefore it is always a good
idea to check the timestamp of any location object before taking any
actions. If both location services are enabled simultaneously, they
deliver events using the same set of delegate methods.
Wait for some time and ensure you make a physical location change for location manager to return back the right location. Note that Significant Location Changes mode is always slower than the regular one.
I am monitoring the users location with these configurations:
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
locationManager.requestAlwaysAuthorization()
locationManager.startMonitoringSignificantLocationChanges()
I have a switch that allows the user to either enter an address manually or allow for GPS tracking. When toggling from manual to GPS location, I'd like to kick the CLLocationManager to update the users location and call the didUpdateLocations event. Otherwise, it just waits and waits to update when it feels like it. Is manually triggering an update one time possible?
from the docs:
startUpdatingLocation
Calling this method several times in succession does not automatically result in new events being generated. Calling stopUpdatingLocation in between, however, does cause a new initial event to be sent the next time you call this method.
so you could stop and immediately restart the location updates to trigger it manually!
Is manually triggering an update one time possible
Yes, but not with startMonitoringSignificantLocationChanges. You will need to call startUpdatingLocation. Note that even then it may take several calls to your delegate, and several seconds, before you get your single usable update.
What I do (example code here) is to watch both the horizontalAccuracy and the timestamp, and stop when I either get a sufficiently accurate location or too much time elapses.
Start it when you want to start scanning for updates, but not when you want an immediate location.
If you want an immediate location, request it with manager.location. If the response is nil then no location is currently available and you need to wait. If a location is returned you can check the timestamp to determine if you can use it.
I want to verify what happens if I call startMonitoringSignificantLocationChanges on an instance of CLLocationManager and then call stopUpdatingLocation. The documentation says to call this method when my app no longer needs to receive location-related events, but there is also a separate method stopMonitoringSignificantLocationChanges. So I'm not sure if calling stopUpdatingLocation would also stop these.
The two are related but independent. They are started and stopped separately.
One common scenario is to call stopUpdatingLocation and startMonitoringSignificantLocationChanges in applicationWillResignActive in order to increase battery life.
When your app returns to the foreground the significant location change is stopped and location monitoring is started again
I want to get the location updates for every 30 secs.In foreground and when the app is in background.Also how could I know that my location is updating or not if I use simulator.please provide some help.
You don't, you get location update when the device moves. Location update are not really meant to be polled, but rather you are notified when there is a new location available.
Just create a instance of CLLocationManager and start call the startUpdatingLocation method. Then the delegate of the CLLocationManager will start receiving location updates. Just be aware that if you keep this running for a long time it will drain the devices battery faster.