Understanding iBeacon region monitoring latency and testing - ios

In order to test region monitoring I have added some UILocalNotifications that gets triggered when the app is launched. I have also enabled background mode communicates with BLE accessories for the App I am using to test this.
Now, what I have observed is that it does not always get launched with the same time ranges (as Apple's documentation already anticipates there will be a certain latency to avoid false positives). However I am trying to test the overall iBeacon region monitoring reliability and for this reason I drafted some basic test cases:
Case 1:
Phone is switched off AND beacon is turned on (App is not running).
Phone is switched on
Expected result: I expect iOS to wake up app.
Actual result: this does not always happen immediately. It does after long long time (e.g. 20 minutes). Is there an official upper limit for this?
Case 2:
Phone is on AND beacon is turned off (App is not running).
Beacon is turned on
Expected result: I expect iOS to wake up app.
Actual result: It does usually happen.
Case 3:
Phone is on AND beacon is turned off (App is not running).
Beacon is turned on
Wait until app is woken up (background running).
Turn beacon off.
Wait until region is exited.
Kill App (whilst running in background).
Turn beacon on.
Wait until App is woken up (background running).
The above flow usually works. However I noticed that it works well when we wait until 5 occurs (region is exited and this event is detected by the app running in background).
Any suggestion or further use cases? I struggle in particular with case 1.

Related

Terminated App not wakeup with iBeacon packet

Can iOS receive iBeacon packet in sleep state and wake up the app?
I killed an app and restarted, then kept the phone in sleep mode. The device was was in beacon region when device reboot and I kept the device screen off after reboot.
My iOS app is not waking, so I suspect its not receiving iBeacon packet.
I checked the system log and found that the didEnterRegion procedure is not getting called.
Does app wakeup works incase of force terminated app and does iOS receive iBeacon packet in reboot and immediate sleep state?
If I make screen on then it starts working immediately but if screen is off after reboot its not receiving iBeacon packet.
Yes, iOS CoreLocation will launch your app on region entry or region exit, and works even after force termination after iOS 7.1.1. You will only get the appropriate callback if you set up your CLLocationManagerDelegate in the AppDelegate's didFinishLaunchingWithOptions method. If you do not set this up in that method, then CoreLocation will not know to make the callback after app launch.
Testing entry events across an app restart can be a little tricky, so here are a few tips to avoid pitfalls:
If is critical that your app think that it is "outside" the region when it was last running. If it was "inside" the region when it was last running, it won't necessarily get another entry callback because it will think it never left. When testing, make absolutely sure you get a didExit callback or a didDetermineState callback that says it is out of region before you kill the app or reboot. Verify this with a NSLog statement, a local notification, or some custom UI indicator added to a screen of your app.
If you reboot an iOS device, CoreLocation is not fully initialized right away -- I have seen it take 5 minutes after the screen comes on before I get any callbacks. Be sure you wait long enough.
Once CoreLocation is fully initialized, region entry events typically happen within one second of when the beacon comes into range. However, if the limited bluetooth hardware assist pattern slots are all full on the device (typically this happens if you have a few other beacon apps that have used them all), then entry events fall back to software scans that happen only every 10 minutes or more. An entry event can take that long in such a situation. Make sure you wait long enough before assuming it isn't working.

iOS/iBeacon/Swift: How to keep the app running, after phone is restarted

I understand any iBeacon application can continuously run in the background, if CLLocationManager is appropriate used; we were able to get it working based on the thread iBeacon monitoring and ranging in background. From the thread iBeacon Notification when the app is not running it appears when phone is restarted, we get the notifications from the underlying API if the app enters into the proximity/zone of the previously specified UUID (bcos iOS briefly invokes our app).
Based on above 2 threads, I am assuming we should be able make ranging happen continuously in my app. We want to be able to read RSSI always (even if user restarts phone or moves out/in of the zone).
How can I make ranging happen 24 by 7 (even if user restarts phone)? I know cellcontrol has done it https://www.youtube.com/watch?v=BvJJjBspP-4

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 background monitoring stops working

I have an app that monitors iBeacons entry/exit events. When it receives an event it forwards the event off to a server. The app continues to work (e.g., the server continues to receive updates) after the user minimizes and/or force closes it (so it works correctly in the background).
However, after a phone has been away from any iBeacons for a sufficient amount of time (e.g., overnight) and is brought near iBeacons again, the app stops receiving enter/exit updates until the user opens it up again (brings it into the foreground). If the user minimizes/closes the app at that point, updates continue to work correctly in the background.
Is anything that I need to do to allow long running monitoring updates in the background? After a while does iOS stop background monitoring?
Note: I am running iOS 9.3.1
iOS Apps are supposed to be able to detect beacons indefinitely in the background when they have been granted "always" location access.
This is the second report I have heard like this, so I wonder if it is a bug or a change in a new iOS version. Reporting your iOS version would be helpful.
One possibility: the network calls may be being blocked and not the beacon detections. You could test this hypothesis by adding NSLog statements to :
Log on beacon detection
Log on successful and unsuccessful connection to the server.
Once you add the above, reproduce the issue where you don't see events on your server. Then connect your phone to XCode and go to Devices, and look at the recent NSLog output to see:
Is there a line indicating the beacon was detected?
Was the server connection successful or not?
If you find it is the network connection that is failing, you may be able to correct the situation by requesting additional background network permissions.
EDIT: One other thing you might try when a detection is not made is launching a different beacon scanner app in the foreground like Locate. This will force an OS bluetooth scan and it might kick off your app's detection. If this works, it would tell you that bluetooth scanning had been suspended across the phone.

Receive signal from beacon while app is in the background

I have a iOS app that interact with a beacon.
Also have a function to detect the signal from a beacon and if the signal is out of range I want to store something in the database (in this case core data)
func updateDistance(distance: CLProximity) {
UIView.animateWithDuration(1.0) { [unowned self] in
switch distance {
case .Unknown:
self.view.backgroundColor = UIColor.grayColor()
self.distanceReading.text = "No Beacon Signal Detected"
updateDatabaseWithLocation()
}
}
}
So the app works fine as long as the app is running in foreground.
My understanding is I can also have the app in the background when user not actively using the app and still get signal from beacon.
If so, how can I accomplish this task? I added the following to info.plist and still didn't work.Also is it possible to update the database as well?
You can only range beacons (which is what gives you access to the distance approximations) when the app is running. As soon you leave the app (press the home button, navigate to another app, etc.), iOS will suspend the app, and ranging will stop working. Continuous usage of Bluetooth radio in the background would drain the smartphone's battery quickly.
You can, however, have your app subscribe to be woken up into the background when the smartphone enters and exits range of a beacon (or a group of beacons). This is called region monitoring, and it's the same mechanism that geofencing uses.
Now, "enter" and "exit" events in and on themselves won't give you access to distance approximations. However, since iOS will wake your app into the background for a few seconds to handle these events, ranging will actually resume for the duration (assuming you haven't stopped it before the app got suspended), before iOS puts the app back to sleep again.
You can even extend the "few seconds" into up to a few minutes with a background execution task.
All of the above doesn't require the use of background modes—only the "always" authorization to use Location Services.
You can't ordinarily keep the app running in the background indefinitely with beacons. Background support is heavily regulated by Apple, and is only allowed, e.g., for navigation apps, or music apps. People do on occasion try using the "location" background mode to keep the app alive in the background (and thus capable of ranging beacons), and some even reported being able to get it past the review process, but that seems to be more of an exception than a rule.
Should you decide to give it a try anyway, you need to:
enable the "location" background mode,
set allowsBackgroundLocationUpdates to true on your CLLocationManager instance,
start regular location updates: startUpdatingLocation.
This should keep the app running in the background even if you leave it.

Resources