CoreBluetooth - centralManagers method didDiscoverPeripheral becomes least frequent to nothing in sleep mode - ios

I am using CoreBluetooth and the callback method didDiscoverPeripheral gets called frequently when the app is foregrounded or backgrounded or the device is locked with device screen still turned on.
But as soon as the screen is turned off / blacked out (Sleep mode) its callback frequency is reduced to almost nothing.
What might be causing this? The device battery is full and Bluetooth turned on.
Please help me with this issue.
Thanks.

Two main things you should be aware of regarding CoreBluetooth and background operation:
1.) The CBCentralManagerScanOptionAllowDuplicatesKeyflag is ignored after an app is put into the background. If you saw a peripheral while in the foreground, you will not get another didDiscover callback for that same peripheral in the background (during the same scanning period). You can test this by having your peripheral powered off, and only powering on after your central has been sitting in the background for some time. You should then receive the callback.
2.) The other issue is that callback time for peripheral discovery is throttled down in the when in background. If for example, you would discover a peripheral in 1 second in the foreground. It could take as long as 60 seconds to discover that same peripheral in the background.

I was unable to find any direct answers as to why the iOS behaves this way. Although I have found an alternative way to resolve this.
I am implementing a PeripheralManager along with the CentralManager. That way even though the iOS device's screen is turned off, i have control of the iOS device.

tdevoy is correct, however, I would give slightly more optimistic time-to-discovery values. In my experience it requires only 1-2 seconds for discovery when either one or both devices are in the backgrounded/suspended state.
If you are not receiving callbacks when your app is in the background then there is a good chance your code is slightly wrong. In the WWDC 2013 CoreBluetooth video the engineers provide explicit instructions about how to achieve the behavior you desire. Once you are able to receive the callbacks you could schedule and present a UILocalNotification which would give similar behavior as receiving a text message.

Related

ios app, running accelerometer while the app is in the background

I have an app using accelerometer. When a certain motion is detected, i am trying to make my iphone vibrate. While the app is in the foreground, and I conduct a certain motion, it vibrates. But it does not when the app is in the background.
I have a counter that detects this motion. When I execute this motion while in the background for three times, although it does not emit any vibration, after I transition back to foreground, the counter is increased by three. So I know the accelerometer is working. Or is putting the motions in a queue and executing it when the app comes back to foreground.
And I'm not making a rookie mistake by touching the phone's vibrate to off.
I'm quite not sure where to go from here. Is iphone inherently not capable of capturing and processing accelerometer data while in the background? Or is there something I'm not doing correctly?
In iOS there are only a certain type of activities allowed in background. Here you can check them: Background Modes.
I'm currently working in an app that uses sensors like the accelerometer and I get updates from it using the CoreLocation delegate method didUpdateLocation, since using the GPS to locate the device is one of the Apple allowed background modes. I hope this helps you!

For some iPhones the beacon didenterregion gets only called after screen is turned on

We are using the standard Apple Location SDK and Estimote iBeacons to trigger an Action on the didenterregion call.
For many users it works good but some have the issue that the it´s only triggered after the turn their screen on for example with the rise to wake function or by pressing the home button.
We already asked the users to reset network settings and of course restart the device.
Is anybody experiencing similar issues? Any idea what could help?
Many Thanks
Stephan
bluetooth use power plus is operated by some of the cpu functions which are disabled when you suspend your phone.

How to detect iBeacon in iOS app when screen is off?

Still fighting with iBeacon monitoring for screen-off mode in my iOS app.
In my experiment, when the screen is turned off, the delegate method "locationManager:didRangeBeacons:inRegion:" is still triggered continuously, but, as soon as the screen is off, the signal disappears accordingly(RSSI=0, beacon.accuracy=-1.0), and then, 10 seconds later, there is no beacon found at all.
I found some important information in this post saying that "iOS uses beacons in two different ways: region monitoring and beacon ranging. The latter does NOT work in the background ..., or when the app is terminated.
CLLocationManager will ONLY fire off ONE delegate call when a region is entered. If you start monitoring for a region while inside of that said region, the entry delegate will NOT be called. Your app will have to manually call the CLLocationManager’s requestStateForRegion method. Once you’ve exited the monitored region(s), CLLocationManager will call the didExitRegion approximately 30-45 seconds later."
Now I tried to call the "requestStateForRegion:" method continuously when the screen is off. The result is:
If my iPhone is already in the iBeacon region, the delegate method
"didDetermineState" gives "CLRegionStateInside" continuously;
When I hold my iPhone and walk outside the iBeacon region, or just
shut down the iBeacon's advertising, after 30-45 seconds, the
delegate method "didDetermineState" turns to "CLRegionStateOutside"
and keeps in "outside" state;
When I hold my iPhone and walk inside the iBeacon region, or turn on
the iBeacon's advertising again, the delegate method
"didDetermineState" still gives "outside" continuously and NEVER
TURNS BACK TO "inside".
What I need is, when the screen is off, I can detect as soon as my iOS device enters the iBeacon region. Asking for help...Thanks in advance.
Have you added the NSLocationAlwaysUsageDescription in your info.plist? I can really recommend you to follow this tutorial which goes through all this.
When you start monitoring, there's always an initial call to the didDetermineState delegate. This is how you can figure out if you're already in the beacon region. From then on, you can continue relying on didEnter/didExit (didDetermineState is also called alongside these). The only catch is, if the user turns Bluetooth off and then back on again—you will lose any state transitions that ordinarily would've happened during that time—so it's a good idea to call requestState after you detect Bluetooth is back on, to get caught up on the current state.
All in all, there's no need to call requestState continuously, and you can't ordinarily even do so when the screen is locked—iOS will put your app to sleep, per my answer to your other question. Unless you're using Background Modes to keep the app running in the background, but then you must be able to defend it when you submit your app for review, as Background Modes are reserved for very specific use cases. You should rely on automatic calls to didEnter/didExit/didDetermineState, aided by requestState if Bluetooth is turned off and on.
When I hold my iPhone and walk inside the iBeacon region, or turn on the iBeacon's advertising again, the delegate method "didDetermineState" still gives "outside" continuously and NEVER TURNS BACK TO "inside".
Keep in mind that depending on hardware capabilities of your iOS device (you haven't mentioned which one you're testing with), the "enter" event might take a while to trigger. The guys at Radius did some testing long time ago, and it was up to 15 minutes for iPhone 4S on iOS 7.1. That's b/c iPhone 4S doesn't support offloading BLE scanning to the Bluetooth chip, unlike newer iPhone models. But even on these newer models, there's a limit of how many scans can be offloaded to the chip, which Radius also measured to be 30 (on iOS 8.3 and with 3 different iOS devices).

iBeacon monitoring in background

I read that iOS7.1 was supposed to have fixed iBeacon monitoring in the background. I am seeing that it takes about 15 minutes for a monitored beacon to call the didExitRegion while in the background, regardless of what background capabilities I add. This makes it rather unusable for my scenario.
Is there any way to get more frequent updates? Short of that, are there any other ways to keep my app alive in background so that I get more frequent monitoring and possibly even ranging?
Background detection times still take up to 15 minutes on iOS 7.1, especially on older models like the iPhone 4S. I did tests to demonstrate this, which you can read about here: http://developer.radiusnetworks.com/2014/03/12/ios7-1-background-detection-times.html
It is possible to keep your app alive in the background so these detectuons are faster, but unless you have a navigation or audio app, allowing app store approval for special background modes, you are limited to 3 minutes of background activity at a time. See here for details:
http://developer.radiusnetworks.com/2014/11/13/extending-background-ranging-on-ios.html

Advertising with iBeacon when app is in background

I have been digging all forums and tutorials about transmitting in background mode with iBeacon. Until now, I couldn't find something solid which can help me. My app can successfully receive and transmit but when I press home button, transmitting stops and connection on other device/devices disappear. In myApp.plist, I added required keys but still nothing works. The question is, how can I make my app keep transmitting in background mode?
iBeacon will not advertise (transmit) in the background. If you need this you will not be able to use iBeacon and will instead need to implement your own BTLE advertisement (which will run in the background).

Resources