sometimes didExitRegion event missed of iBeacon - ios

Sometimes app didn't execute the didExitRegion event in the following cases.
Bluetooth OFF
Keep device/beacon away
Switched OFF the Beacon
After the missed didExit event, didEnter even also won't execute because the iOS(OS/App) thinks beacon still exists. It happens until restart the power cycle of the beacon.
I have tried to overcome this issue programmatically. But it seems like I didn't fix it.
I have tried the following steps to overcome this issue
Based on the ranging/didDetermine status I have executed didExit event manually. (It didn't help)
I've tried with restart the beacon monitoring (It didn't help)
Aspected Result: didEnter/didExit events must be worked when the beacon is coming to the range or exiting from the range.

Related

Refresh iBeacon state

I am newbie with iBeacon and need some help. Already found some useful info from other topics but still searching for answers.
Is there a way to receive notification about my state at position right after app is killed or after I switch ON bluetooth? Now I got notifications only after state changes.
Example: I need to have notification when I got to point 'A'. But I got there and realized that my bluetooth is OFF. I switched bluetooth ON and didn't get anything because iBeacon thought I am 'INSIDE' from beginning. This happens when app is not foreground (but not 100% times, sometimes iBeacon 'rescan' and send his state again).
I need to somehow manually refresh iBeacon state and get methods didDetermineState or didRangeBeacons to work. I tried to stop and start monitoring after app is killed to forces the notification, but doesn't seem it works. I know there is a way to get this 'refresh' after turning ON display, but it could be perfect to also get it in other situations when needed.
Lots of location and beacon events can wake up an app that is running in the background, but relatively few events are sent to apps that have been killed via the task switcher or were never launched since boot.
The only bluetooth events capable of launching a non running app are:
didEnterRegion (for CLBeaconRegions)
didExitRegion (for CLBeaconRegions)
Other events received only by foreground/background running apps:
didDetermineStateForRegion
CoreBluetooth device discovery
CoreBluetooth power state changes
The last one is the event you care about, but it just won't be sent to apps that are not running. One alternative may be to rely on other location events like Significant Location Change, which launches a non-running app when the user moves "significantly" (e.g. to the next cell tower). You could register for these events and check Bluetooth state at that time. This may be the best you can do.

iBeacon did enter region does not trigger when user turns manually bluetooth on

I am testing iBeacon region monitoring and doing the following steps.
1: Precondition: Bluetooth is on in the phone and App is not running
2: I turn the beacon on
3: The app gets launched following a location event (beacon region)
4: I turned the beacon off
5: The app is still running and detects the did exit region event
6: I then kill the app manually (it is ok to do so, region monitoring will still work)
7: I turn off Bluetooth on the phone
8: I turn the beacon back on
9: I turn on Bluetooth again on the phone
10: I expect to... see below (Expected result)
Expected result: the app should wake up following entering the region (I tested this without manually switching the Bluetooth and it works)
Actual result: does not happen.
Why does 10 not happen? Is this a bug in iOS?
Turning Bluetooth off doesn't usually work as a good way to test monitoring. Enter and exit events only happen when the region's state (i.e., CLRegionState) transitions from "outside" to "inside" (and vice versa). If you turn Bluetooth off, the state goes to "unknown"[1] (because how would the device know if you're out or in with Bluetooth disabled), and thus if you switch it back on, and it transitions to "outside" or "inside," it won't actually trigger an event by design.
You can test that by implementing the didDetermineState method, in addition to didEnter and didExit. Start with the beacon turned off, confirm via didDetermineState that the state is "outside." Turn Bluetooth off, turn the beacon on, turn Bluetooth on. You will see didDetermineState with state "inside," but no didEnter. (It works the same the other way around, i.e., if you start with the beacon turned on, and turn it off while the iPhone's Bluetooth is disabled. You will see didDetermineState "outside," but no didExit.)
Note: this test only works in the foreground. It looks like in the background, didDetermineState is not enough for iOS to wake up the app to handle the event—it needs to be didEnter or didExit.
[1] A little clarification here as well. When you disable Bluetooth, there won't actually be an explicit call to didDetermineState with CLRegionStateUnknown. This is because I suspect that iOS stops delivering any beacon events when Bluetooth is off. How did I arrive at the conclusion that it really changes to "unknown" then? I added an NSTimer that calls requestStateForRegion (which in turn forces an asynchronous call to didDetermineState) every second. When I turn Bluetooth off, didDetermineState calls stop arriving. But as soon as I turn Bluetooth on, these calls resume, and the state is "unknown"—before it changes to "outside" or "inside" depending on the current state of the beacon. Again, per the note above, all of this is with the app in the foreground.
(Same mechanics actually apply when you start monitoring already in range of a beacon. Before you start monitoring, the state is "unknown." When you start monitoring, the state transitions to "inside" our "outside" (depending on whether the beacon is in range at the time when monitoring starts), but this does not trigger didEnter or didExit. Here too you can verify this with didDetermineState.)

iOS didRangeBeacons called after didExitRegion

I'm experiencing a strange problem with iBeacon monitoring in iOS.
The test I'm running is,
1.Start monitoring for beacon region.
2.Wait a few seconds and then turn on the beacon.
3.didEnterRegion is called and I call startRangingBeacons.
4.I start receiving regular callbacks through didRangeBeacons.
5.I turn the beacon off, and continue to get didRangeBeacon callbacks for a second or two.
6.Then I receive didExitRegion.
7.Now the weird bit, I then get one further call to didRangeBeacons.
If I turn the beacon back on after this then didEnterRegion is not called, despite the fact that didExitRegion was called. It seems like the rougue call to didRangeBeacons means iOS now thinks the beacon is in range again.
Is this the behaviour people would expect? Or does this indicate a problem with my code?
EDIT:
I'm seeing this behaviour on an iPhone 4 running 7.0.6, if i run the same test with a 5C running 7.1 and a 5S running 7.1.1 everything is fine.
I wouldn't expect that behaviour either. However, in the discussion of didRangeBeacons:inRegion: it says:
The location manager calls this method whenever a beacon comes within range or goes out of range
This could be the explanation of the behaviour you are referring to in bullet 7.
It is not mentioned, however, whether this goes out of range call is performed before or after the monitor delegate calls. Similarly, this does not explain why you are no longer receiving didEnterRegion: calls.

iBeacons issue: Did enter region triggers multiple times

I'm working with a sample app for iBeacon region monitoring functionality. The Issue(not sure if it is) that I was unable to resolve is "didEnterRegion:" fires continuously for more than 2 times when I enter the region. This happens to send the local notification more than once or the times that this method fires when the app is in minimized mode.
Can anybody tell me how to resolve this.
Thanks,
It is common for a glitch in iOS to cause a didExitRegion event followed within a second by a didEnterRegion event. You can filter these out in your code by storing in an NSDate variable the time you last exited the region. When you get a didEnterRegion callback, you simply ignore it if the exit timestamp was within the last few secs.
If you are really getting these continuously as you say, something else is wrong that you may need to fix. It is possible that your iBeacon is not transmitting at least once every three seconds. This would cause constant exit/entry callbacks.

iBeacon: Unable to detect broadcaster - Intermittent

I came across this tutorial (http://www.appcoda.com/ios7-programming-ibeacons-tutorial/) about iBeacon which I found interesting. I've downloaded their source code and able to run well.
Anyway, I noticed one strange thing. There are times, when I run the broadcaster first instead of the receiver, the receiver seems to not be able to detect any beacon but if I run the receiver first, only then the beacon can be detected.
I've tried looking into other tuts but iBeacon seems like a new technology and not much reference can be found yet. Can any of you guys who had get their hands dirty into this iBeacon thing shed some light on this intermittent issue?
Your help are much appreciated.
The issue you're seeing is because the receiver app only starts 'ranging' for beacons if it detects that you have entered a region. If you start the broadcaster first, you're already inside the beacon's region, so your app might not start ranging. This sentence in the article is the clue:
Launch the receiver app and carry it far away from the broadcasting beacon and then walk towards it to simulate entering the region.
Monitoring for a beacon means that your app will only be notified when you enter or exit a region you've defined. The radius of this region could be up to ~50m, so if you're just sat next to the receiver, you shouldn't trigger one of these events unless you turn the receiver off and on again. Monitoring can be done whilst the app is running in the background or the foreground.
Ranging for beacons in a region means that the app will be notified once per second with a list of all beacons that the device can see in the specified region (ordered by distance). Ranging will call the locationManager:didRangeBeacons:inRegion: method of your CLLocationManager's delegate. The list of beacons will be constantly updated as you move around inside / outside the region and your distance to the beacons changes. Ranging is intended to happen whilst your app is in the foreground.
If you would like the app to continuously listen for beacons, try calling
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
in your viewDidLoad:, instead of in your didEnterRegion: method.
Its due to current location delegate available methods. Add this method also -
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
}
This will fix the issue.

Resources