I would like to use region monitoring in iOS , for location based alerts/calculations.
I'm worried that it would drain the battery.
I searched for it on the iOS reference , and couldn't find any evidence for it.
Is that service available at all times , regardless of the region monitoring (i.e. scanned every minute or so...) or should I use the "significant location change" API instead ?
update : so , battery usage isn't dramatic. Its pretty good actually.
would like to receive some advice regarding switching between the modes (region/standard).
After checking for almost 2 weeks , I can tell that region monitoring does not significantly drain the battery.
As a matter of fact , it will be an active service in iOS 5 for sure , as the built-in reminders app will use region monitoring 24/7.
Region monitoring shouldn't have anywhere near the same affect on battery life as location tracking does.
According to Apple's developer documentation, region monitoring is built upon CoreLocation's "significant-change" location service. In order to conserve battery life, this service does not poll position information using aGPS, but instead simply tracks changes in the user's current cell tower.
Whenever the cell tower changes, iOS calculates whether any region boundaries were crossed. If a region crossing occurs while an iOS app is not running, iOS automatically wakes it up (or relaunches it) in the background so that it can process the event via the didEnterRegion:/didExitRegion: callbacks.
Related
I am working on an app that needs to call an API for every 100 meters the user walks for. I need to make the app work even if it is terminated by the system.`
I was thinking about region monitoring as it will work in the terminated state as well, but since it depends on Wifi and cell phone towers, it might not be accurate in my case as the user might be out on a remote hike.
For precision, standard location updates work well, but they don't work in case the app is terminated by the system.
So my question is can I use both standard and region monitoring services together? I can put a distance filter of 100 m and get continuous updates in the foreground and background from the standard location services and each time update the region for the region monitoring services, in case the app gets terminated, the region monitoring service can take over and send me location updates.
Are there any pitfalls with this approach?
I did lots of google search but haven't found any solotions that match my need.
So I came up with my own solutions but not sure if it's feasible or not.
I need to monitor more than 20 regions. So at the first time, I'll start monitoring the current user's location and I get 19 other available locations that I can monitor, let say the radius to monitor is 100 meters. So right now the delegate didEnterRegion should be called? I don't really care about this. But when user moves more than 100m from original location, delegate didExitLocation will be called, and by this time, I'll update new regions to monitor (by sending new current's user location to server and I'll get list of new regions to monitor), and I will still monitor this new user's location and still get 19 other regions that I can monitor.
Is this solution feasible? Have anyone tried?
Does this solution still work if the app is suspended, and if it consumes lots of battery?
This is actually Apple's suggestion Core Location Programming Guide:
To work around this limit, consider registering only those regions in
the user’s immediate vicinity. As the user’s location changes, you can
remove regions that are now farther way and add regions coming up on
the user’s path.
However, it's not clear how much time you get when didEnterRegion: is called in the background, so it's not clear if you have time to make a server call if running the background. The "significant-change location service" information says:
If you leave the significant-change location service running and your
iOS app is subsequently suspended or terminated, the service
automatically wakes up your app when new location data arrives. 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.... 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.
You could try the combination of region monitoring, making a server call in didEnterEter region and then calling beginBackgroundTaskWithName:expirationHandler: to make sure you have enough time. The combination of region monitoring + server calls + background processing is going to hit battery life, though.
EDIT: You could also create "mega regions" of a large area that contain many smaller regions. When the user enters those mega regions, set up and add all the smaller regions you are interested in, and when they exit, remove them.
What should be the correct approach to identify time spend around a beacon[not within a region] in background. I am able to do this when app is in foreground using didRangeBeacons and some business logic.I read on few forums that ranging does work when app has registered for location updates in background, but i am having no success. I have added the location updates key for UIBackgroundModes in plist.
I am using estimote beacons and their sdk.
I see two possible solutions here:
Listen for enter and exit region events, store the timestamps and then use them to calculate the time span on exit. If you define your region so that it encompasses only one beacon, monitoring the region will be equivalent to monitoring the beacon. The only thing to keep in mind is that iOS imposes a limit of 20 regions to be monitored at the same time - so this solution doesn't scale above 20 beacons.
Use ranging in the background. Apart from the UIBackgroundModes, you also need to start regular location services, i.e. startUpdatingLocation.
Beacon ranging delivers events normally while an app is running in the foreground. When your app is in the background, this service delivers events only when the location-updates background mode is enabled for the app and the standard location service is running.
(this is from CLLocationManager class reference, section "Using Location Services in the Background")
Note that ranging in the background will be draining the battery life more than usual, and Apple also requires justification for using the background modes. Unless there's some value for the user of your app coming from the background modes, they might choose to reject it. All in all, use the background ranging wisely! (:
I need my app to know user's position at all times, even in background. My app receives a set of regions of interest I need to check if user crosses. I don't know the size of those regions beforehand, so I need to listen for location updates with high accuracy. Then, I discard the use of the significant-change location service. Moreover, I need to call a service regularly for data updates even in background as well.
So, it seems that there still are two options:
1) enabling the background mode for location services and using the standard location service
2) region monitoring, which doesn`t seem to require enabling any background mode
However, I don't find information about the accuracy of region monitoring. My question is: taking into account that I have the coordinates of the regions I want to detect if the user is in, that I need high accuracy, and that I need to perform regular async services calls in background if location services are enabled (with a timer), what option should I choose?
Another thing: my app has to support iOS 5+
Thanks in advance
First of all, I would like to suggest you to drop iOS 5 from your support. If it is the customer's request, I would like to suggest you to convince them to drop this. See: The market Share for iOS. The market share for iOS 5 and below is less than 2%, the time spent to optimize for those devices are not worth it.
Personally, for the app that I developed in the last 6 months, I only support iOS 7 and above.
As for your question, you can choose both the options. They are not conflicting with each other. The app that I developed have location service in the background that sends the current location of the user to the server every minute and the same app also has region monitoring for crime zone. The user will receive notification when he/she enters the zone.
For how to keep the app active in the background, you may check this thread: Background Location Services not working in iOS 7
For Region monitoring, you may check this thread: Region Monitoring Glitch on iOS 7 - Multiple Notifications at the same time I posted a bit of code related to a glitch.
I am testing some GPS algorithms with the battery life. I just wrote a very simple app using core-location framework and the app update the gps location every second.
I am wondering how can I change the time interval to update my location, like 10s, 1min, etc?
And when my app is at the background it's stop updating the GPS, do you know how to keep it updating at the background?
be aware that iOS usually does not allow background operations in most cases.
But at least there are three options to "permanently" determine the location:
As you wrote: determine location all the time when your app is not in background. (1)
determine location all the time - also in background. You need to update your Info.plist and add location as a required background service (required for location tracking, Google Latitiude for instance) (take a look at api)
get location updates only when the location changes significantly.
You are not able to change time intervals or something like that. You only have theses three options - and you can get location information only once when you need them, but that was not the intent of your question.
I am wondering how can I change the time interval to update my
location, like 10s, 1min, etc?
This is not possible and it would not make sense, because the GPS chip needs the same power if it a position is needed once a second or evry 10 seconds. Of course you can ignore positions if you dont like them (if they come to often).
The settings of desiredAccuracy influences the power:
kCLLocationAccuracyBestForNavigation: enabled GPS and Acceleration sensors
kCLLocationAccuracyBest: enables GPS but no Acceleration sensors (Cell Tower locating if needed)
kCLLocationAccuracyHundredMeters, kCLLocationAccuracyKilometer, kCLLocationAccuracyKilometer: more likely to use Cell Tower or Wifi locating if available.
That uses less power (more likely) but accuracy is lower.
And when my app is at the background it's stop updating the GPS, do
you know how to keep it updating at the background?
If your read Apple's LocationAwarnessGuide ypou find the info, how to set the correct key in Info.plist file.
Since ios 6 there is an additional variant, which should save more power:
There is the method: didUpdateLocations (note: plural!):
This will deliver all locations at once such that it ios does not need to keep your application living in background. Once the app enters foreground you will receive all positions at once.