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
Related
I am trying to figure out the most efficient way to check whether a user has moved after a certain period of time (for example 15 minutes).
If they have not moved more than 200 ft, I would then like to display an alert that says "you have been here for 15 minutes."
I know enabling background location services will eat up the battery, so I would like to check the user's location every 5 minutes or so. Is there a clean way to do this without destroying the user's battery? I don't really know where to begin. Any assistance would be wonderful!
Thank you!
Just use a repeating NSTimer that fires at your desired interval & retrieves the location. Then compare it against the previous recorded location. Polling for the location every 5 minutes or so is not going to have a massively detrimental impact on power consumption.
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.
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.
Let's say, Tiny Tower. On this iPhone game, you can have shops in your tower. You can suspend or turn off the iPhone, but when you return to the game, you will be reported about the shop winnings during your time away.
There are also push notifications when a building is complete etc.
I fear I do not understand how that works, exactly. I'm not asking for the exact solution, I just need to know where to begin researching. One idea I had some time ago was like calculate the amount of seconds the user was away (current time minus the time when you left) and then calculate shop processing for every one of these seconds. But I'm not sure of that.
A better way would be to calculate before you close the app.
Figure out what time it is, then calculate when in the future certain tasks will be completed. This way, you can schedule push notifications to the server ahead of time.
If you calculate after you have re-opened the app, and you can't run processes with the app closed, how will it know when to push?
Take a look at this article about push notifications to understand a little bit better how they work.
http://blog.boxedice.com/2009/07/10/how-to-build-an-apple-push-notification-provider-server-tutorial/
For offline games you add temporal logic to your items and recalculate when game is launched. For online games you retrieve game state from the server, which is constantly recalculating for all users, even disconnected ones.
Game most probably does not actually process in the background (most apps are not allowed to do anything while in background). When you relaunch the game, it calculates how much time has passed, and then processes all the events that would have happened in the meantime.
Additionally, as Paul.s mentioned in comments below, as well as other people in other answers have suggested, on iOS4 you can use local push notifications scheduled before close.
It is either server side execution of the game or if it is a game of chance or something like Farmville where it's determined by time duration.
If you were to make a server and/or game like this then you would need to decide which route to take.
If it will be something where the user has good days and sometimes bad days then you'll need a lot more server power. however, if it's something like time based then you would be able to tell the last time they were logged in and the next time that they should be awarded. you can also take this idea and for each variable that you store, you store how long it takes to be complete and the start time. Then you would do a simple If then o see if the item is ready. The same thing can work for a number of visitors. Where you have 10 visitors per item per hour. If you have two items then each hour you will receive 20 visitors.
I'm looking for a bit of guidance from anyone who has worked with Core Location on the iPhone. My app is almost complete, I'm just trying to finish off one last thing for my client.
My app is to assist users with their workouts. Similar functionality to MapMyRun. It has a timer screen with a Start/Stop button and a Reset button. When the start button is tapped, the timer starts counting and Core Location starts tracking the users progress, calculating speed and distance. The issue I'm having is with core location trying to find the users current location. Scenario below:
Day 1
User has gone out for a jog and uses the app to track their progress, user has jogged for an hour, workout is saved. Everything works as it should.
Day 2
User decides to go jogging again, this time in a different area than yesterdays jog. Lets say 10 miles away. So they start the timer, but core location takes some time to initialise to the users current position. This causes the distance field to jump irrationally as core location tries to determine the current location.
I've explained why this happens but my client is not very happy, they don't want to see the distance field jump, which is fair enough.
So I'm wondering if anybody has a nice solution to initialising core location to the users current location. I could perhaps break the link between core location and the distance field for a certain period of time which will give core location a chance to get an accurate reading.
Any help greatly appreciated.
Regards,
Stephen
Stabilise the readings by reporting "calibrating..." until the position readings roughly match the speed readings, which are generally more accurate than position.
Yeah, CoreLocation and the GPS-tracking really can annoy one.
some time ago someone had a quite similar problem and got posted some ideas and code:
CoreLocation
Pherhaps this helps. But still I would show an activityIndicator untill you got your exact location. And it's not like GPS-tracking is a matter of tenth of seconds... Just explain your client by referencing to navigation systems in cars. Pherhaps he will understand then....
Try to find the user current location before going in to the App. So that you can directly show the users current location with out taking much time.