Registering for significant-change location versus startMonitoringForRegion:desiredAccuracy: - ios

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.

Related

Swift Region Monitoring Local Notification trigger

I'm doing an app to trigger a local notification when a region is entered.
However, sometimes when the phone is locked, the notifications didn't pop up even I've been in the region area for a while. The notification popup will show only when the power/home button is pressed(phone still in locked mode).
In general, all seems to be working except that sometimes the notification will show only when power/home button is pressed to awake the phone although it is still locked.
Hope someone can enlighten me please! =)
According to the developer documentation. In core-location framework, two services can give you the current location information.
The standard location service is a configurable, general-purpose solution for getting location data and tracking location changes for the specified level of accuracy.
The significant-change location service delivers updates only when there has been a significant change in the device’s location, such as 500 meters or more.
You need to use standard location services to keep monitoring location in background
If your iOS app must keep monitoring location even while it’s in the background, use the standard location service and specify the location value of the UIBackgroundModes key to continue running in the background and receiving location updates. (In this situation, you should also make sure the location manager’s pausesLocationUpdatesAutomatically property is set to YES to help conserve power.)

CLLocationManager region monitoring and airplane mode

I am developing a location dependent feature. The uses case is this:
User receives data and notifications based on their location.
Location is actually the city/town they reside in more accurately a
region based on the city.
Then they hop on a plane/train and go to another city. I want to
be able to detect that send them local notification to change
their location settings and if they accept to start providing them
data based on the new location i.e. city. Very important to this
part of the usage is the Airplane mode which is usually turned on
during the travel and then turned off when the user arrives at
their destination.
I thought region monitoring will be the perfect technology for that. However there is no way to find out if the user had gone outside the region when using Airplane mode. There will be nor crossing event and I am unable to request the state for the particular region. Also in that case if the app was terminated the system will not wake it up for crossing event because there is not one.
Is there a way to reliably handle that situation.
I also thought a replacement technology for my use case might be the Visit monitoring.
Thanks!

iOS region monitoring, to monitor more than 20 locations

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.

Tracking location in background in iOS: standard location service vs. region monitoring

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.

About updating the GPS at the background

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.

Resources