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?
Related
So, we need to use region monitoring. I noticed that commenting out the startMonitoringSignificantLocationChanges doesn't change the Regions sample app behavior.
Actually, I don't deeply understand what it actually does, and how can I tell if a specific location (a few meters sensitivity) was visited if mobile cells are located hundreds of meters away from each other.
It seems that region monitoring is calling the didEnterRegion and didExitRegion as expected, and I don't see the point in the sample app to harness significant location change(SLC) as there is no treatment in the app delegate's in the case of launchOptions containing UIApplicationLaunchOptionsLocationKey.
To my understanding, SLC should be used only when the app needs to know that the user has changed location, and can voluntarily requestLocation to get the new location in the didFinishLaunchingWithOptions if in background.
Region monitoring and significant location changes are different.
Region monitoring creates "geofences" around a location and causes the system to send you messages when the device enters/exits the defined region. Region monitoring is specific to a particular location.
Significant location change monitoring lets you get notified when the user moves a significant distance, but using less power than keeping the GPS "lit". SLC monitoring is not tied to a specific location.
Region monitoring does not require SLC monitoring, and vise-versa.
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.
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.
Registering for significant change location the app only receives coarse location updates (if the device moves from cell to cell), however according to this post
If background applications can't launch automatically how does Cardcase launch on a location change?
its also possible to use startMonitoringForRegion:desiredAccuracy: and have the app woken up when a location change occurs.
Presumably the desiredAccuracy can be pretty fine, so does this imply its a back-door way of registering for significant changes to location but with a fine grain?
Is it permissable by the app store therefore?
In my testing I have observed that the region monitoring is sometimes not very accurate, i.e If I drive past a region I might not get any indication of having entered or exited the region. (under the hood it might be using something similar to significant location change)
Also the desiredAccuracy here is really the buffer (in meters) around the region where notifications should not be generated , this is to prevent multiple notifications if you are at the edge of a region.
Not really. You have to specify a specific region, and you only get sent notifications when the region is entered/exited.
It's the same mechanism that the Reminders app uses for sending reminders, they create a region around the location, for instance work, and register for region notifications.
While it might theoretically be possible to create lots of little regions next to each other, it's not really intended for that and will probably cause problems down the line.
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.