3

I am working on a project where I first wanted to advertise a device as an iBeacon and make it possible to connect to that device via Core Bluetooth at the same time. Besides the fact that this is not easily doable (a device cannot advertise as an iBeacon and CB device at the same time), I noticed that the iBeacon part seems unnecessary - discovering peripherals with Core Bluetooth seems to be basically the same as discovering iBeacons.

My first Question: Am I right in assuming this? Or does iBeacon provide anything that central/peripherals in CB do not? Especially in regard to background advertisement/searching?


The only issue I can see right now is that the CLBeacon gives me both an rssi and an accuracy (and from this, the approximated proximity is calculated). With Core Bluetooth, centralManager:didDiscoverPeripheral:advertisementData:RSSI: gives me only an RSSI. Is there any way to retrieve the accuracy here so I can calculate a proximity? This is important for me and I guess relying on RSSI only for the proximity will give me less accurate results?

My second Question: Can I get the accuracy that I get with iBeacon in Core Bluetooth or a similar measure to calculate the proximity?

BlackWolf
  • 5,239
  • 5
  • 33
  • 60

1 Answers1

4

You can calculate your own distance estimate with RSSI using an algorithm like the one I posted here:

https://stackoverflow.com/a/20434019/1461050

The trick is that you will need as many RSSI measurements as possible averaged over a time window of 20 seconds or so to reduce the noise on the estimate.

The main advantages of using CoreLocation APIs to detect standard iBeacons vs. using CoreBluetooth to detect custom beacons are:

  1. A variety of cheap off-the shelf hardware is available for the iBeacon standard.
  2. CoreLocation can scan for iBeacons in the background (likely using hardware assist on iPhone 5+) in a way that can automatically launch your app relatively quickly, even if the user did not manually launch it since boot. As of iOS 7.1, even if the user kills the app from the task switcher, CoreLocation can re-launch it into the background if an iBeacon is detected. I do not believe all this is possible with CoreBluetooth.
  3. The iBeacon transmission allows you to easily read the UUID/major/minor identifier combination in iOS without pairing. This 20 bytes of data (with the major and minor fields able to be set to arbitrary values) is more than you can get from a 16 byte Bluetooth Service UUID.
  4. You don't have to roll your own software for distance estimation.
Community
  • 1
  • 1
davidgyoung
  • 63,876
  • 14
  • 121
  • 204
  • thanks for the nice writeup, this helps me a lot. I assume there are no really good methods to advertise as an iBeacon and via CB at the same time? My solution would have been to switch between the two every couple of seconds or so, but that seems ugly, so I thought about dropping iBeacon and going with CB only. – BlackWolf Jun 17 '14 at 16:11
  • Oh and yes, you are right about major/minor: I actually use them right now to transfer data. The UUID has to be same on all devices, so I guess that doesn't count, right? But since I want to establish a CB connection anyway and BTLE can do that without user interaction I suppose this will be fine. – BlackWolf Jun 17 '14 at 16:15
  • 1
    You can't advertise both simultaneously, because the iBeacon transmission takes up all the advertising space available. You can switch back and forth at a rate of about 1Hz. I did this to emulate transmitting as two different iBeacons at the same time. See here: http://stackoverflow.com/a/21553009/1461050 – davidgyoung Jun 17 '14 at 16:25
  • 1
    One clarification: The UUID does not have to be the same on all devices -- you can look for up to 20 different UUIDs simultaneously using 20 different CLBeaconRegions. So while this does not give you access to 16 bytes of information, it does let you know which out of 20 UUIDs is transmitting -- effectively a little more than four bits of additional information. – davidgyoung Jun 17 '14 at 16:29
  • I see, thanks for clarifying. Since switching between the two seems like it could horribly wrong (in particular when thinking about CB connections), I will first try to go the CB only route I guess. – BlackWolf Jun 17 '14 at 16:56
  • Hi @BlackWolf did you succeed in the corebluetooth version of the code? Actually, I am creating a indoor navigation app and the CLBeacon class seems to provide less accurate distance. Any help on the same would be appreciated. Thanks in Advance. – Alkesh Fudani Mar 24 '17 at 10:46
  • About your 2nd point: In the [CoreBluetooth documentation](https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothBackgroundProcessingForIOSApps/PerformingTasksWhileYourAppIsInTheBackground.html#//apple_ref/doc/uid/TP40013257-CH7-SW8) it says "Upon being woken up, an app has around 10 seconds to complete a task.". So CB can wake up your app. Not sure about what happens after user kills the app, though. – heyfrank Apr 08 '20 at 16:03
  • About your 3rd point: The UUID of the iBeacon is unique to your beacons not to one of your beacons. So you only have 2x2 bytes for data that you can transmit without connecting. – heyfrank Apr 08 '20 at 16:19
  • CoreBluetooth can wake up an app in the background only for GATT service operations including (a) first time peripheral discovery (b) central connecting (c) read/write request from a central. This is more limited than Core Location, which gives you entry/exit background events as often as every 30 secs. And the beacon ProximityUUID of CoreLocation does not have to be common to all your beacons. You can just have to declare them to iOS up front. A single app can start beacon ranging for *hundreds* of beacon regions each with a different ProximityUUID. – davidgyoung Apr 08 '20 at 17:35