12

First: I have an iPad Air 2, and an iPhone 7. For further reading we estimate that the app is active and open on iPad and in background mode on iPhone. The app is exactly the same, even with same Bluetooth Service UUIDs and same DataLocalNameKey.

I want to write an app that can advertise a bluetooth service in background and is able to discover this service (optimal in background too). As I already read I can't use apples beacon technology cause there it's only possible to get scanning/notified by beacons in near in background (I tested this, works fine) but not to advertise. So I started to use CoreBluetooth as described in the mentioned SO answer cause there it's possible to advertise in background.

My app calls didDiscoverPeripheral method in CBCentralManagerDelegate on the iPhone (app in background), so it detected the iPad. The isAdvertising property of CBPeripheralManager on iPhone is true. But didDiscoverPeripheral is not called on iPad. I'm a little bit confused. One option is my iPad is not able to detect the iPhone anymore for some reasons or my iPhone is lying and it's not advertising.

So i thought I'm just a little bit of dumb and googled for "CoreBluetooth debug apps". I found Vicinity and AltBeacon. And with both apps the behavior is the same! If you background (press home/sleep button) the advertising app, the browsing app is not able to discover it anymore. If you open the backgrounded the app it will instant discover it. Both apps mention that its possible with them to broadcast in background.

Am I doing something wrong; is this behavior expected? Did I misunderstood the framework? Can you confirm this behavior?

To confirm this, the fastest way is to install Vicinity on two devices (you have to add the NSBluetoothPeripheralUsageDescription key to Info.plist) set one device to broadcast and press the home button.

Community
  • 1
  • 1
flashspys
  • 844
  • 9
  • 20

2 Answers2

12

This isn't anything specific to iOS 10 -- it's always been this way on iOS. On iOS, apps simply cannot send out standard Bluetooth LE advertisements when they are in the background. They have to be in the foreground to do this.

That said, there is limited support in iOS for apps advertising GATT Services in the background. This uses a proprietary technique that only works with other iOS devices that are looking for those services. (Because it uses a non-standard proprietary scheme, the same technique won't work for beacon advertisements, for example.)

Here's how Apple describes it:

...you should be aware that advertising while your app is in the background operates differently than when your app is in the foreground. In particular, when your app is advertising while in the background:

  • The CBAdvertisementDataLocalNameKey advertisement key is ignored, and the local name of peripheral is not advertised.
  • All service UUIDs contained in the value of the CBAdvertisementDataServiceUUIDsKey advertisement key are placed in a special “overflow” area; they can be discovered only by an iOS device that is explicitly scanning for them.
  • If all apps that are advertising are in the background, the frequency at which your peripheral device sends advertising packets may decrease.

Read more here: https://developer.apple.com/library/content/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothBackgroundProcessingForIOSApps/PerformingTasksWhileYourAppIsInTheBackground.html

davidgyoung
  • 63,876
  • 14
  • 121
  • 204
  • Okay. I added a service to my advertiser like `cbPeripheralManager!.add(CBMutableService(type: random cbuuid, primary: true))`. And I added this uuid to `scanForPeripheralsWithServices`. So everything apple mentioned is fullfilled here: There is a ServiceUUID on advertising side and I have an iOS device which is explicitly scanning for it. Don't work anyway. – flashspys Sep 21 '16 at 20:01
  • 1
    There may not be enough room in the "overflow area" if you have other apps installed that advertise in the background. Try uninstalling these apps, as it sounds like you have tried several. – davidgyoung Sep 21 '16 at 22:05
  • 2
    I deleted all my apps and reinstalled my dev app. Nothing changed – flashspys Sep 22 '16 at 18:53
  • 1
    Any progress here? Trying to figure out how this "overflow area" really works in iOS – Alexander Telegin Nov 02 '16 at 15:00
  • @flashspys I am facing exactly same problem, have you find any solution. – Ritesh.mlk Nov 13 '18 at 16:28
  • @davidgyoung Sir can you please suggest how do we explicitly scan for them. I have tried Google Nearby, Eddystone, Altbeacon, iBeacon, P2pKit & several other solutions but I just want that my app users can get an notification if someone is nearby (through beacons off-course). Today its been three months on this issue & I still don't know if its possible. ... [Crownstone](https://crownstone.rocks/2018/06/27/ios-advertisements-in-the-background) said that they are able to read overflow area (Which is one hot encoded) – Ritesh.mlk Nov 13 '18 at 16:35
  • 1
    Sorry, Rishi, nothing has changed here since the answer above. You effectively cannot advertise in the background on iOS using standard beacon frames. You may want to look at this clever alternative: https://github.com/Decemberlabs/AltBeacon, but do not confuse that project's name with the AltBeacon advertising format which shares the name, but cannot be advertised in the background on iOS. – davidgyoung Nov 13 '18 at 16:51
  • Thanks for the quick response. Sir I have tried Altbeacon you said and it is publishing in background, But many beacon scanning apps can't find the UUID advertised in background, how ever it is showing the CoreBluetoothLocalName atleast which is enough because now I just want to notify users that my app user is nearby in background. Now the problem I am facing is its not scanning in the background which it works in eddystone & iBeacon case there is a delegate method named foundDevices, Which is only called when the app is in foreground, if I go background the delegate method doesn't execute – Ritesh.mlk Nov 14 '18 at 07:52
2

it was a bug in ios 10.0.(1) and partially fixed in ios 10.1

src: https://forums.developer.apple.com/thread/51309

Daij-Djan
  • 49,552
  • 17
  • 113
  • 135