If I set my CLLocationManager's desired accuracy to be kCLLocationAccuracyKilometer (accurate within a kilometer) will the iPhone deliver a better position eventually, when it gets it ? Or will it stop at my desired accuracy. I can't find this in the documentation.
The idea is that I need a fast fix for the location, but then I would like to go more accurate. Will I have to code this myself, or is it done for me automatically ?
I don't know if the following is 100% correct, but I am pretty sure it works like this: the accuracy filters are primarily designed to save energy. So if you specify that kCLLocationAccuracyKilometer is enough for you and the OS is pretty certain that it can locate you accurately within 1 km using triangulation only, it won't even power up the battery-draining GPS unit. So regarding your first question, the location manager will stop as soon as it reaches your desired accuracy.
Regarding the second question: I don't think the accuracy filter has any influence on the time you receive your first location update. The OS often caches your last known location and will deliver that one almost instantly even if you have specified a very high accuracy. Subsequent location updates will get more and more precise.
You should be able to easily test for yourself if this is indeed the real behavior.
Set the best accuracy you need (but not more, because location services consume too much power). LocationManager will call didUpdateToLocation of your CLLocationManagerDelegate every time accuracy is improved. Stop updating location as soon as you can to prevent battery exhausting.
No, it will stop at the specified accuracy. If you request only kCLLocationAccuracyKilometer then the GPS receiver won't be powered on and it will get no better than WiFi or Cell tower triangulation. [The only exception would be if another app in the background (like TomTom nav) already has the GPS on for high accuracy fixes, then you might get the high (<300m) accuracy fixes too).
If you want better you have to request it and you might as well request it immediately, you'll get the fast fix (1000m accuracy) fix right away and in a minute or two you'll get the high accuracy GPS fix (well, it can take 30 seconds up to 10 min depending on several things). No special coding is required, just specify the accuracy you eventually want.
Related
In my testing, I have found that the results of my tesing regionMonitoring on iPhone4S has been a little under par.
That being said, here's what's happening in my testing:
I try to test by setting an alert for the same location when I drive. Sometimes, the alert goes off right on the dime, but most of the time it does not. I have been wondering about the accuracy of this feature. The feature saves power, which is great, but what good is it if timely updates are not received by the device. It defeats the purpose. In this case the users are going to give bad reviews to the app - because they'll have to switch to startUpdatingLocation which is power hungry
Since I drive around for testing, and because the updates are not received - in time, I believe, the alert does not go off. Is my 50.0m radius too small? I can increase it - but the user will be alerted a little too soon!
The feature relies on user's device being passed by one cell-tower to the next. Therefore, is the user out of luck (for using this feature) if he/she happens to be in area where there are not enough cell towers?
Thoughts? Suggestions?
Regards....
50 meters is pretty aggressive even for GPS on a handheld. Try throwing up a wider net first, then switch to more aggressive location monitoring when you were say, within 500-1000m of the target location.
It's impossible to set desiredAccuracy for significant location change. I have tried and it returned default value 1414 for horizontalAccuracy. Does region change update method is better in terms of accuracy? Is it possible to set it and what is the maximum allowed accuracy for region change update?
There is no accuracy for -monitorForSignificantLocationChange. It is a built in monitor that is designed to be used for broad updates, low on accuracy (but can be accurate enough depending on the application), and great on battery life. It works on the same principal as the -monitorForRegion method. It will update when it thinks you have moved a significant bit (e.g. cell tower transition, new wifi connection, etc). It will also steal/borrow location from other apps that use location as well. So it can be pretty accurate considering how it gets your location.
If you need precise location in the background... you are going to have to sacrifice battery life. The only other alternative is to sacrifice some location accuracy. In my experience, the location returned via the significant change and region monitoring is pretty accurate.
Region monitoring can take accuracy settings. But it mainly just comes off your -locationManager settings. Once you enter the background, you are at the mercy of the system again. I'm not 100% sure if your -monitorForRegion will retain the set level of accuracy, my guess is no. Mainly due to the restrictions on battery life. Hope this helps.
Here is the scenario. I need to have an application which polls a web service with the users location every 15 minutes whether in background / foreground.
At the moment I:
Start / Restart the location manager with accuracy highest and distance filter none.
Wait to get within desired accurancy.
Store reading
setDesiredAccuracy to be: "kCLLocationAccuracyThreeKilometers"
setDistanceFilter to be: 1000
Set a performSelector:#selector(getLocation) withObject:nil afterDelay:900
Start again from step 1.
I want to make this the most battery saving method possible and would like to see what fellow 'stackers think of the option above and if you guys have any other suggestions.
Thanks
James.
If you're not targetting iOS3, consider using the 'significant change' API, it's supposed to be the most efficient for this kind of scenario.
Why not register the app for significant location change and just use that? Plenty of apps do (including some of mine) and it's quite battery-friendly. In fact, NOTHING HAPPENS unless the phone does a cell tower hand-off. If the phone sits somewhere for hours, there's literally NO battery impact. In your approach the whole CL framework and the GPS hardware has to fire up every 15 minutes.
In the end I got the application to start / stop the location manager every 15 minutes on a performSelector: WithDelay.
Basically when the CLLocationManager gave a reading within the desired accuracy I lowered the CLLocation to significate changes then set the application to take another reading 15 minutes later, changed the accuracy to one of the highest settings and repeated.
Hope this helps anyone in the future.
Thanks
James
I am wondering how CLLocationManager's distanceFilter work. According to the docs,
The minimum distance (measured in meters) a device must move laterally before an update event is generated.
So has the phone already gathered the location, but distanceFilter just prevents my call back from getting notified?
I don't see how using the distanceFilter saves battery life, it seems like a Catch-22.
I believe quantumpotato's comment is close. Through Apple's own testing, whatever, they've determined what power level they have to use on the antenna to get readings within a certain accuracy.
As someone who has used this API, I agree with you, it's not perfect and it is somewhat misleading. Think of those flags as "desired levels" and depending on the type of app you want to make, you just need to pick one.
I have looked at several variations on the Reachability example such as the Donoho change and erica saduns UIApplication extension, but none of these allow you to determine the quality of your 3g connection.
Is there a programatic way to see signal strength and link quality?
I think you need to decide exactly what you mean by quality and also understand that it constantly changes.
The only really accurate measure is unfortunately historical - i.e. you can do a download or upload test and measure the time it took and any packet loss, jitter, delay etc and this will let you know what the quality was when your test was run.
The reason I say it is historical is that this does not guarantee that it will stay like this for any given time - for example you may move between cells (or rooms in the case of WiFi), or several other users in your area may start utilizing the bandwidth heavily.
It may be that a simple download or upload test is sufficient for your purposes to (I am guessing...) decide if your want to run your application in a certain way, and then you can build in further checks into the application itself to see if you need to adapt to a change in the network (e.g. you could trigger on the time for a particular application message transaction to complete)