Periodically 'ping' the iPhone GPS? - iphone

I'm trying to create an app similar to TravAlert which apparently 'pings' the GPS periodically to figure out where you are. Unfortunately, I'm having a heck of a time figuring out how to do it.
I can't use an NSTimer to fire off the GPS checks because NSTimer doesn't run in the background (which this app presumably must do). I can't use Local or Push notifications as "timers" because they automatically come with a notification and I don't want the use to know every single time that the GPS was queried.
I also tried using CoreLocation's startMonitoringSignificantLocationChanges and that works to a degree, but I can just see the case where the user happens to be in a region of poor cell service (apparently startMonitoringSignificantLocationChanges uses cell tower triangulation as a means of determining location) and thus the app fails to fire.
Any idea how TravAlert does it?
Thanks!
P.S. I'm not trying to rip off TravAlert by making a better app - this is for a college class and unfortunately neither my professor or anybody else in my class has the faintest idea as to how to replicate TravAlert's GPS "ping".

startMonitoringSignificantLocationChanges is the right choice for your app. You can get finer detailed location whilst your app is running. The other option to run the GPS in the background is intended for navigation apps hooked up in a car due to high power consumption.

Related

Use of Standard location service for tracking traveled distance in a foreground/background app

I have to develop a kind of GPS navigation application that needs to constantly keep track of the position of the user, which is moving by car.
In the specific, I don't have to display the current location on a map but just to record its position with the best possible precision in order to calculate the total distance traveled.
Of course the application needs to continue its work in background if the user switch to another app, a phone call come in or something like that…
From the tests I have made and from what I have learned from this useful post (and from the documentation), it seems to me that the best choice in this case is the Standard location service, with the application configured with the UIBackgroundModes = location in the .plist file.
In this way it will continue to receive the location updates even if in background and it will never be suspended by the OS (this is actually true only if [locationManager startUpdatingLocation] has been called). This is also confirmed by this guys.
I have personally verified that is true simply by running the app with Instruments and the Memory monitor module where you can see the various flags about the app states, putting the app in background first with UIBackgroundModes set to location and startUpdatingLocation active, and after without it.
1) I'm now wondering what to do when the app is terminated when it is tracking the position. I don't want to loose any location updates so I need to wake up it again whenever a new update is available.
The documentation say:
Important: The applicationWillTerminate: method is not called if your
app is currently suspended.
But because in my case it will be never suspended (it will stay in background but not suspended), my logical conclusion is that applicationWillTerminate will be always called and so I could register for a Significant location update or Region monitoring inside of this method in order to be waked up and then restart the Standard location service.
Is applicationWillTerminate the right place to put this code?
2) An application working in background but not suspended could be terminated by the OS for no other reasons than a very low memory condition or for my app don't properly respond to a memory warning? (the user could also manually close it). I was concerned if applicationWillTerminate wouldn't be called in some way.
3) Could Apple not approve an app which constantly use the standard location services in background because of its quick battery drain?
Have you ever had approve problems for similar apps?
since you are asking many questions which you shoukd not do here, i cam give you only aswrs to a part of it.
if the app is terminated, then you cannot restart it anymore.
This is usually the case when the user terminates the app.
Dont worry Apple ( ios) will not terminate your app. your app will not use much memory, games with huge bitmap graphics are more likely to be termin.
evry gps app will drain the bat. that is not a reason for not aproving.
suspended means that app is not in background mode, it is sleeping. you will not receive Gps, so there is no need to call you on terminate. you have to save data before, see the apple docu on background modes and app life cycle.

Is it possible to get distance from user location to specific location in background in IOS?

I need to calculate distance from user location to specific location, when the app is in background, and get a local notification based on that.
Background location tracking is totally possible, and I have already done that, but is it possible to execute a block of code, containing some condition checking and based on that update and get a local notification?
I am not getting any proper solution. Is there any way to do so?
Can you help me please?
Yeah, you can definitely do that. I'm doing it in an app right now. Use significant location changes, or regions, as previously suggested, to keep the pressure off the users battery as much as possible.
We observe regions (and significant location changes where regions are not supported by the device) then check a few things and fire off a local notification if needs be.
We started with a basic prototype to prove the concept and I highly recommend that approach as a way to get familiar with the location and notification frameworks.
Start with the Location Awareness Programming Guide. Most everything you need to know is in there. (Most things that aren't in there are simply impossible for an AppStore app.) See also Tracking the User's Location in the iOS App Programming Guide.
The best tool for what you're describing is likely "Shape-Based Regions." You can basically draw a box on a map and say "when the user enters or leaves this box, let me know." If at all possible, this is the tool you should use. It has the least impact on battery life.
If you absolutely cannot solve the problem any other way, it is legal to request background location delivery with startUpdatingLocation (and the appropriate background mode in Info.plist; see the above docs). An app that tracks your route while you hike would be be appropriate for this kind of setup. But you should avoid it if at all possible since it's a major battery drain.
You will want to update for significant locations in the background: http://mobile.tutsplus.com/tutorials/iphone/ios-multitasking-background-location/. Then you will want to create a location notification based on that.
My issue is that I am not sure if you can create a local notification in the background.

How to make iPhone track itself on a map?

For Example, I travel from San Diego to La, I want the iPhone to track how long it was from San Diego to La and tell me the result?
When your app is in the background it could still receive location info when there is a significan location change such as new cell tower. Your app could monitor the significan location changes as well as regular gps when it's available and calculate the time difference.
Check out Starting the Significant-Change Location Service
http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html#//apple_ref/doc/uid/TP40009497-CH2-SW10
Also this is a good tutorial for using significan time change notifications:
http://www.mindsizzlers.com/2011/07/ios-background-location/
For basic MapKit usage check out this tutorial.
You can use CoreLocation to track the phone with GPS, storing the position every so often (either do it every X minutes, or every X miles/degrees-latitude-longitude.
The CLLocationManager class is what you want, most likely. You give it a delegate that receives events, and start it polling. To conserve battery, you don't necessarily want it to be polling continuously, but you can set it up to automatically turn off and then back on again in a little while.
Displaying it on a map is slightly more complicated, but still quite easy to do. If you need Geocoding, you'll probably need to use the Google Maps API.

Stopping CoreLocation background updates

My app registers for background location updates (not Significant Change. I need more granularity than kilometers)
That part works fine. I just want to stop the updates after the app has been in the background for 60 minutes. The way I'm doing it right now is to call stopUpdatingLocation in my CLLocationManager delegate.
However, I am unsure if this will actually stop my app from receiving background location updates, or if it will, but will just ignore them. Ideally, I'd like to not have my app be responsible for battery drain except for a small period of time after user activity.
Apple's documentation tends to send me in circles on this one. Right when I think "Executing Code in the Background" is about to spill the answer, it directs me to "Location Awareness Programming Guide." Right when that one is about to get specific about this question, it sends me back to "Executing Code in the Background." :)
I'm not sure whether your app has total control over this, but the docs for stopUpdatingLocation do state the following ...
Disabling event delivery gives the receiver the option of disabling the appropriate hardware (and thereby saving power) when no clients need location data
Which would suggest that should your app be the only one requesting background location data, and you request it to stop the GPS receiver would disable the appropriate hardware to save on power, which I think it was you're looking for.
What I can suggest is that you enable Power logging in Settings -> Developer, then run your app for an hour or so to a point where you think GPS is disabled, run for another hour and then compare the power usage in Instruments. This should provide you with a much clearer picture.
Calling stopUpdatingLocation will indeed stop GPS and so on, but if you place this call inside locationManager:didUpdateToLocation:fromLocation of your CLLocationManager delegate, then it might never be called.
Keep in mind that this method is only executed whenever a more accurate position or a (according to the active distance filter) significantly different position is available. If the device does not move at all and if the circumstances affecting the accuracy also do not change, it may not be called for hours (I have verified it for several minutes myself) and GPS will also stay enabled for this long.
For apps that only work in the foreground, you can use an NSTimer of 60minutes, but for apps that run in the background, the closest to a working solution that I have found so far, is a scheduled UILocalNotification. But even that requires the user to confirm an alert, before the app is restarted and able to turn the GPS off.
Maybe beginBackgroundTaskWithExpirationHandler: is the key to a better solution, but I have not completely figured it out, yet.

Background GPS in iOS. Is this possible?

I was wondering if it was possible to get the location of the iPhone with an app that isnt running, or at least running in the background. What I want to do is have the iPhone send a push notification when it arrives at a certain coordinate. Is this possible? If so, could someone put me in the right direction?
Thanks,
Ben
Yes, it is possible. Your application can ask to be notified of significant location changes or to simply continue using the GPS while executing in the background. The former—the approach recommended by Apple—uses less power at the cost of accuracy (this blog post indicates that the updates are accurate to roughly 500m), while the latter is as accurate as the device can manage. This is all detailed in the iOS Application Programming Guide and and the Location Awareness Programming Guide.
If you simply want your application to be notified when the device moves into a particular region, you may want to look into CLLocationManager's startMonitoringForRegion:desiredAccuracy:. If the device moves into a particular geographical region, your app is launched (even if it's not running!).