locationManager:didEnterRegion and didExitRegion are never getting called :iBeacon - ios

While testing with beacons (ios devices) i found the listener beacon giving some unexpected behavior. locationManager:didEnterRegion method is not getting called even if a beacon enters a region. But the locationManager:didRangeBeacons:inRegion: is getting called correctly, and detected beacons are shown there.
- (void)startListening{
self.locationManager = [[CLLocationManager alloc] init];
[self.locationManager setDelegate:self];
NSUUID *myProximityUUID = [[NSUUID alloc]
initWithUUIDString:IDENTIFIER];
_beaconRegion = [[CLBeaconRegion alloc]
initWithProximityUUID:myProximityUUID
identifier:kPFTransmitterIdentifier];
_beaconRegion.notifyEntryStateOnDisplay = YES;
_beaconRegion.notifyOnEntry =YES;
[self.locationManager startMonitoringForRegion:self.beaconRegion];
[self.locationManager requestStateForRegion:self.beaconRegion];
//[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
}
this is the code i have written.
i need to create a local notification when the listener app enters a particular region even if the app isn't running.

It's possible nothing is wrong with your code. I've noticed that if you turn your test beacon on when the detector is already inside the beacon region (next to it), you will NOT get any notification that you entered the beacon region. That's most likely because iOS did not detect a boundary crossing. iOS seems to notify when it detects that you have crossed the boundary between "out of region" and "inside region" (in either direction) and only then calls the appropriate delegate methods.
To test this, simply turn on your beacon but leave your detector OFF. Then, as indicated by davidgyoung above, walk 200 feet away from your beacon. THEN turn the detector ON and walk toward the beacon. You should get a "didEnterBeaconRegion" notification when you enter the region.
Another thing you can try is to implement the "locationManagerDidDetermineStateForRegion" delegate method, which is called whenever the state of a defined monitored region changes, which happens whenever you turn on your detector. If you do that, you should get a callback even if your detector is already inside the beacon region when initiated. But note this does not happen in the background so you still need the other callbacks as well.

Here's the troubleshooting procedure I would use:
First get it working in the foreground. Run your app in the foreground, and turn off your iBeacon (if it does not have a switch, then pull out the battery or take it 200 feet away.) Wait 10 seconds (you should get a out of region notification in this time) then turn back on your iBeacon and verify you get an in region notification. If you do not get one, I suspect there is something wrong with your callback definition. If this is the case, please post that code.
Once you have it working in the foreground, try to get it working in the background with the shoulder button. Always get the phone to a known state of not being in the region while being in the foreground (using the procedure above), because it takes a long time to make this happen in the background. Once you know you are out of the region, put your app into the background by turning off your screen. Then turn back on your iBeacon. Since you have _beaconRegion.notifyOnEntry =YES, you should get a callback within one second of when you force your display on by hitting the shoulder or home buttons.
Once you have this working, you can go on to letting the phone detect the presence in the background without hitting the shoulder button. Understand though, that this can take longer than you might expect. See this discussion for more details.

Have you registered your app for background location updates in the info.plist file? You need to add a row with the array UIBackgroundModes and add an item location: See reference

The didEnterRegion method not get called when using notifyEntryStateOnDisplay before monitoring sometimes.I also have tested this condition on my device.Probably you can test once without notifyEntryStateOnDisplay or notifyOnEntry condition .It will help.

Related

iOS location services not returning co-ordinates after some time in background mode

Done with the setting up the required pre-requisites. set distance filter , accuracy filter and using start updating locations.
Able to receive location co-ordinates once moved to background for some time say 10 -15 minutes. Later Didreceivelocation updates not returning any co-ordinates even after the device is moved beyond the provided distance filter. But when app brought back to foreground, it returns location co-ordinates.
Any solution to receive location co-ordinates when ever the user moves to set distance filter irrespective of the app being in foreground or background.
Any way to keep the app to behave as always run in foreground even though app is in background mode?
I think you have to look at this answer to make sure you've set up everything right:
allowsBackgroundLocationUpdates in CLLocationManager in iOS9
"This new property is explained in the WWDC session What's New in Core Location"
Put a code in that view controller
$if ([self.locationManager respondsToSelector:#selector(setAllowsBackgroundLocationUpdates:)]) {
[self.locationManager setAllowsBackgroundLocationUpdates:YES];
}

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.

didRangeBeacons method not getting called when display is Off

i'm working with ibeacons from couple of weeks, i was trying to post some local notifications , when the iphone hits the beaconregion(when proximity near).
It was working fine when the app is in background with locked and with display on, but when my display turns black ,
didRangeBeacons method stopped getting called.
I know by using the
region.notifyEntryStateOnDisplay = true;
we can get notified while the display on.
Is there any way that i can achieve posting notification while the app is background with locked and display off.
Please help me out.
It is totally possible to range beacons in background.
You can go around the limitation by setting this up together with your current location manager or creating a parallel one (which makes no difference, I think). You'll also need to enable background location updates capabilities at your project.
locationManager2 = [[CLLocationManager alloc] init];
locationManager2.delegate = self;
locationManager2.desiredAccuracy = kCLLocationAccuracyKilometer;
[locationManager2 startUpdatingLocation];
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
//Do nothing here, but enjoy ranging callbacks in background :-)
}
Now, you'll need to have a good explanation when Apple ask you why do you need the background location updates mode in your app. They're very picky with that.
If you have requested both beacon entry notifications and ranging, and you ENTER a new region while the screen is locked, you will get a didEnterRegion message (or possibly the didDetermineState message) followed by about 5 seconds of ranging messages. If the user doesn't wake up the device during those 5 seconds, the ranging messages stop.
Thus you can't really filter based on proximity to a beacon from the background. If you try to wait until you get a range value of near then more than likely you won't get it because the device stops sending your ranging messages before the user gets that close. You then won't get any more notifications about that beacon region until the user either leaves the region again or wakes up the phone and brings your app back to the foreground.
An app I'm working on posts a local notification when it receives a didEnterRegion (or didDetermineState) message. That causes the screen to light up, but doesn't seem to extend the amount of time you get ranging notices.
No, this is by design and reflects iOS's goal of conserving battery. You can only count on didRangeBeacons: while the app is foregrounded.
David Young has a pretty thorough writeup that may help clarify.
I have the same problem which Madhu has. Instead of didUpdateToLocation, I used didUpdateLocations which is worked for me. Now I am able to range beacons while the app is in background or terminated with locked and display off.
On iOS 8.4
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
//Do nothing 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(

Region Monitoring and App Closed

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.

Resources