Region Monitoring and App Closed - ios

I have a problem with my App based in Region Monitoring in iOS;
Suppose that I have a Monitored Region with 300 meters radius, and my location is 350 meters off the center of that region (but I am into a car moving get closer to my region).
If I close my App in that moment the GPS is turned Off instantly and the method "didEnterRegion" is never called. This problem doesn't happen if my location is farther to my region monitored (for example 500 meters away)
Is possible to fix this? I tried with "Background modes" setting the "Required location services" in background, but this make to use the GPS instead "Region Monitoring" and the GPS never stops.
The problem with Region Monitoring is that this function never works when the user is already "inside the region", then this causes a lot of problems for the in time notification.

First, you don't need background mode for region monitoring to work, region monitoring will continue to function even if you Sleep your device(pressing the top button). Plus Apple can reject your app if you don't use BG mode according to how they need it.
For your issue, if you are already inside and you are not getting a didEnterRegion for whatever reasons, you should use a backup plan. In your CLRegion class you can call containsCoordinate to see if you are inside the region.
You did not get a didEnterRegion call probably for some reason your add region gets reinitialized. I.e. you have re-added your region.

Related

When does iPhone shows solid location icon in the status bar?

I am developing an app that subscribes to user's significant location changes, visit changes and region (geofence) changes. However, I always see a solid location icon in the status bar. Looking at "Privacy->Location Services" settings I see that recently the location was used by my app and some other app.
Also once I set location permission for my app to 'Never', the location icon in status bar disappears.
I am wondering whether the subscription to significant location changes, visits and region changes cause iOS to show the Solid Location icon.
I am actually sitting in my room for half of the day and as a result the phone doesn't change location and I do not expect any location change event to be fired.
What is the exact condition when solid location icon is shown in the status bar?
I've read this question, but I think it is unrelated.
I wanted to cover all aspects of your question and I hope you don't mind a long descriptive answer.
Permission levels:
Never - User denies the app permission to use the location.
While In Use - User has given the app permission to use use the location when it is in use. This means foreground and location access is granted to the app while the user is actively using it.
Always - User has given the app permission to use the location in background and foreground.
The main arrow denotes location use:
The arrow at the right top corner before the battery level indicator can have two shades.
Hollow (outlined) - Indicates that there are apps on the phone that use geofencing
Solid arrow - Indicates that there are one or more apps that actively use the location of the phone including GPS. The solid arrow displays for apps running in the foreground and background.
If your app is utilizing region monitoring then, it gets delegate callbacks for entry and exit events. This often means the phone is being tracked using significant location changes. For region monitoring, you don't need to explicitly register to receive location updates as it is all taken care of by the underlying APIs.
The solid arrow will continuously display in case you have regions that are in close proximity to the phone, my observation is anywhere up to 3KM. The distance is unpredictable and largely depends on the geographic location of the phone, but I have noticed the continuous use of location to trigger regions and then the OS switches back to significant change based monitoring once the region has triggered or the phone has moved a lot further. If this is not the case, then review the LocationManager delegate implementation to make sure the app is not receiving updates more frequently.
On the other hand, if you are registering for significant changes in location to be notified, then the solid arrow will display whenever location updates are delivered to the app.
The solid purple, solid gray and outlined purple arrows in privacy settings are displayed against the apps and are described in the screenshot below.

How to reset region center when exited region in background using CoreLocation

My idea is simple in theory, but am having a really hard time executing it. I want to create a geofence at the user's location, and when the user exits that region, I want to recenter the region at the user's updated location. Here is the flow:
Retrieve user's currently location using standard [CLLocationManager startUpdatingLocation]
On locationManager:didUpdateLocations:, create a geofence at the current location using startMonitoringForRegion, and on subsequent location updates, recenter that region
On locationManager:didExitRegion:, which is usually called from the background to wake up the app, call [CLLocationManager startUpdatingLocation] to retrieve the user's current location to recenter the geofence (centered to the next updated location that is NOT the current region center coordinate).
Sometimes this all works, but more often than not, the geofence doesn't recenter correctly. What's been happening is that the region is re-centered and locationManager:didExitRegion: is immediately called, which puts it into an infinite loop until the app is terminated again. Since it is terminated without a valid monitored region, the app then won't be woken up for location updates.
Is this incorrect usage of region monitoring? I'm trying to play with different ways of tracking user location in a battery efficient way (and not constantly using the standard startUpdatingLocation). Would a combination of signification location change tracking and visit monitoring be more effective?
Thanks!

Region monitoring when device is off

I have a client requirement to monitor a region (say MyHome). To alert the user when he leaves MyHome and reaches back to the location. I can handle it pretty easily using the region crossing delegate methods:
locationManager:didEnterRegion:
locationManager:didExitRegion:
My question is, what will be the scenario if my device is off when I am at MyHome location. I leave the location MyHome, move to a different place and switch on my mobile. Will I get the locationManager:didExitRegion: delegate method fired when I launch the app back and thus will be able to notify that I am away from the region. OR will I have to do anything else to get this possible?
First of all monitoring region is not made for such small area to monitor. You may not get actual results. Now, the answer of your question, yes. It is possible. When you will start your device, you will have delegates method to get hit.

Beacon monitoring keeping location services on, indefinately. iOS

My iPhone app registers for significant location change. When on location change is called, I start beacon region monitoring for all the beacon in certain range of user's location.
My app needs to identify that user has entered into a beacon region (irrespective of whether app is running or not). To achieve this, we did following things:
-- set notifyEntryStateOnDisplay flag to true for beacon regions:
beaconRegion.notifyEntryStateOnDisplay = true;
-- set Required background modes in pList to bluetooth-central. for ref. this link
I am not sure what got it working. But it turns out our app does not turn location services off, once started.
Is it possible to get significant location change update and beacon region entered update when location service is off?
Do I need to set Required background modes to get this working in background?
When you using iBeacon to monitor for specific region it will always display location icon on status bar, even when app is closed.
To disable location service for your app try to call method bellow for all you registered regions when going to background:
- (void)stopMonitoringForRegion:(CLRegion *)region
And to use iBeacon in background you actually need not "bluetooth-central" mode but "location".
You do not need to keep background mode - location updates ON for beacon ranging.
For background execution, just use UIBackgroundTaskIdentifier and your code will work in background as well.
check my answer iBeacon ranging in the background? here.

didEnterRegion order of execution?

So I asked a question about my code relating to didEnterRegion but perhaps I was being too specific, therefore could I ask someone to clarify the order of method calls in more generic terms for region monitoring, specifically when the app is in the background.
My understanding is:
App registers region calling startMonitoringForRegion:
User taps home button or locks device, app goes into the background.
The devices location is monitored at the OS level, separate from the app, the app is never launched by the OS to confirm the users current location.
When the user crosses the boundary into the region, the OS looks for which app originally registered the region and launches that app.
The app is launched in the background, (didFinishLaunchingWithOptions: is not called however), the CLLocationManager delegate is setup and it’s didEnterRegion delegate method is called.
In my case, this sets up a UILocalNotification which is presented immediately (banner displays on home screen if for example another app is in use, or on the lock screen if phone is dormant).
The user actions the notification by swiping in the lock screen or tapping the banner, the app is launched and appWillEnterForeground/appWillBecomeActive is called AND the app delegate didRecieveLocalNotification: method is called if implemented.
This is my understanding, which is probably wrong as my UILocalNotification is never fired if the app is in the background. Could someone clarify which bits are wrong?
After further testing I've come to the conclusion that there's nothing wrong with my code and it's actually appears to be Apples implementation of region monitoring being poor. It seems to be only slightly better than the monitoring of significant location changes, and still relies on changes in wifi networks and cell towers. Even within a major UK city I found didEnterRegion wasn't trigged until you were up to 1000 meters into a mile wide region, if triggered at all. This explains why it works every time when testing though Xcode and forcing the location.
The only work around I've come up with so far is to calculate the distance remaining each time the users location is updated and to manually call the didEnterRegion delegate method when this is less than the regions radius/2. This is supposed to be done automatically by Apples code when you're more than 10m into the boundary, however I found that to be unreliable for the reasons above.
However given you can't get regular updates using the better accuracy of GPS whilst the app is in the background and this is only a problem when the app is in the background, it's not really a solution at all. :o(

Resources