iBeacon is a precise micro-positioning technology based on Bluetooth 4.0 (Bluetooth LE | BLE | Bluetooth Smart) launched by Apple at WWDC in 2013. When your handheld device is close to a Beacon base station, the device can sense the Beacon signal
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
feasycom e5abaca477
Update 'README.md'
2 years ago
LICENSE Initial commit 2 years ago
README.md Update 'README.md' 2 years ago



iBeacon is a precise micro-positioning technology based on Bluetooth 4.0 (Bluetooth LE | BLE | Bluetooth Smart) launched by Apple at WWDC in 2013. When your handheld device is close to a Beacon base station, the device can sense the Beacon signal, and the range is From a few millimeters to 50 meters. Because it is a positioning technology, Apple put the iBeacon-related interface in CoreLocation.framework. The prerequisite for using iBeacon is that the user turns on the Bluetooth function of the iOS terminal that supports BLE and turns on the location information service. After iOS receives iBeacon, it will notify the UUID of the app that uses iBeacon. When triggered by UUID, the App will be woken up.

Although we have not seen any use cases in real life, iBeacon is definitely one of the hottest new topics brought by iOS 7.

In order to understand the difference between the two modes of operation, there are two words you should know:

  1. Monitoring-involves low-power area monitoring, receiving didEnterRegion: and didExitRegion: agent messages.
  2. Ranging-means high-power activities, at this time you can receive the signal strength from each iBeacon and be able to estimate the distance to them at the moment.

Before iOS 7, Apple provided us with the ability to monitor the device entering or leaving a specific area, the core of which is CLRegion. The technology revolves around geographic location and what will happen when entering or exiting that location. Even better, if you specify to receive background location updates in info.plist, then the system can activate your app at the regional boundary.

iOS 7 adds CLBeaconRegion inherited from CLRegion. As long as an iBeacon is detected by iOS, even if the signal may be weak, you are defined as being in the area. This makes the testing process crazy, because even if I wrap all my Estmote beacons with aluminum foil, iOS still thinks I am in this area.

An iBeacon is identified by 3 values: proximityUUID, Major and Minor. The first one is UUID, and the latter two are two 16-bit binary integers. You can build CLBeaconRegion with 3 levels: UUID only, UUID + Major, UUID + Major + Minor. For example, you may want to use a UUID for the entire company and Major for each store. Minor can be used to specify each shelf in each store.

Advertise Ordinary BTLE (Bluetooth Low Energy) peripherals advertise multiple services, iBeacon is different. iBeacon uses advertising information on its own and does not need a real Bluetooth link, because all the required information is already in the iBeacon advertisement.

Start with a brief example:

  1. @implementation ViewController
  2. {
  3. CBPeripheralManager *_peripheralManager; 
  4. BOOL _isAdvertising; 
  5. }
    • (void)_startAdvertising
  6. {
  7. NSUUID *estimoteUUID = [[NSUUID alloc] initWithUUIDString:@"B9407F30-F5F8-466E-AFF9-25556B57FE6D"]; 
  8. CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:estimoteUUID
  9.                                                                 major:2 
  10.                                                                 minor:1 
  11.                                                            identifier:@"SimEstimote"]; 
  12. NSDictionary *beaconPeripheralData = [region peripheralDataWithMeasuredPower:nil];
  13. [_peripheralManager startAdvertising:beaconPeripheralData];
  14. }
    • (void)_updateEmitterForDesiredState
  15. {
  16. if (_peripheralManager.state == CBPeripheralManagerStatePoweredOn)
  17. {
  18.   // only issue commands when powered on 
  19.   if (_isAdvertising) 
  20.   { 
  21.      if (!_peripheralManager.isAdvertising) 
  22.      { 
  23.         [self _startAdvertising]; 
  24.      } 
  25.   } 
  26.   else 
  27.   { 
  28.      if (_peripheralManager.isAdvertising) 
  29.      { 
  30.         [_peripheralManager stopAdvertising]; 
  31.      } 
  32.   } 
  33. }
  34. }
  35. #pragma mark - CBPeripheralManagerDelegate
    • (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral
  36. {
  37. [self _updateEmitterForDesiredState];
  38. }
  39. #pragma mark - Actions
    • (IBAction)advertisingSwitch:(UISwitch *)sender
  40. {
  41. _isAdvertising = sender.isOn;
  42. [self _updateEmitterForDesiredState];
  43. }
  44. @end This example has a UISwitch to switch soft-beacon. There are some pitfalls here. First, it took several milliseconds to turn on the Bluetooth system. CBPeripheralManager can only be used when Bluetooth is activated. As soon as it does this, you will receive the peripheralManagerDidUpdateState: proxy callback. If the Bluetooth power is on at this time, you can start broadcasting the beacon.

Stopping iBeacon is much simpler and only requires one command. If the power of CBPeripheralManager is turned off, all advertisements will also stop. This happens when the app enters the background and you haven't told iOS to keep the Bluetooth service running. If you remember correctly, all services will be restored when the app returns to the foreground.

Estimote There is no conclusion on what type of device is used to perform the function of iBeacon. You can use any iOS device (>= iPhone 4S) and Mac (>= late 2011) Bluetooth chip as iBeacon. There are also hardware companies that provide dedicated hardware. The original intention of Beacon hardware is that you do not need to stick a real iOS device on the wall. Not everyone can put an iPad in every corner of the store. The price of standard iBeacon hardware is $99 for 3 pieces. I bought 3 Estimote beacons at this price.

Estimote Developer Preview Kit Estimote provides a very friendly unboxing experience. In addition to 3 iBeacons of different colors, there are 1 button, 1 sticker, 1 business card of Estimote CEO and co-founder Jakub Krzych, and some warning messages to inform you that these beacons are currently assembled by hand, so there may be firmware bug.

The first thing you need to do after receiving the beacon is to download the demo application of Estimote, which allows you to try Monitoring and Ranging as described above. It also allows you to link each Estimote device to observe their power, firmware version, and the settings of UUID, Major and Minor.

At this time, I was surprised to learn that Estimote uses the "burned in" UUID. The official statement said that this is a deliberate design to prevent hackers and location spoofing from jailbroken devices.

UUID is obvious in the app, and it is also published in several blogs:

  1. B9407F30-F5F8-466E-AFF9-25556B57FE6D

This is also the UUID I used in the example above, which actually creates a simulated Estimote beacon.

The Estimote beacon is completely wrapped in rubber, so there is no physical hardware interface like USB. All settings are done through internal services exposed by Bluetooth and Estimote. It is speculated that a future version of the official Estimote SDK will launch a UUID encryption method for those who are worried about their beacon security.

They also recommend that you use their packaged Core Location and Core Bluetooth instead of the native iOS methods. For the functions provided by the system, I personally dislike using third-party SDKs. The best solution to potential problems caused by you and your neighbor using the same UUID is to use a random Major value combined with UUID to monitor. Once the range is discovered, you do an additional check—possibly for geographic location—whether you are indeed in your own store.

Monitoring iBeacon area If you already have an Estimote or created a soft-beacon as above, the next step is to monitor this area. Here is a working example, the purpose is to update the text label and send a local notification when you cross the boundary of the area:

  1. @implementation AppDelegate
  2. {
  3. CLLocationManager *_locationManager; 
  4. BOOL _isInsideRegion; // flag to prevent duplicate sending of notification 
  5. }
    • (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)options
  6. {
  7. // create a location manager 
  8. _locationManager = [[CLLocationManager alloc] init];
  9. // set delegate, not the angle brackets
  10. _locationManager.delegate = self;
  11. NSUUID *estimoteUUID = [[NSUUID alloc] initWithUUIDString:@"B9407F30-F5F8-466E-AFF9-25556B57FE6D"];
  12. CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:estimoteUUID
  13.                                                            identifier:@"Estimote Range"]; 
  14. // launch app when display is turned on and inside region
  15. region.notifyEntryStateOnDisplay = YES;
  16. // isMonitoringAvailableForClass:Returns a Boolean indicating whether the device supports region monitoring using the specified class.
  17. if ([CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]])
  18. {
  19.   [_locationManager startMonitoringForRegion:region]; 
  20.   // get status update right away for UI 
  21.   [_locationManager requestStateForRegion:region]; 
  22. }
  23. else
  24. {
  25.   NSLog(@"This device does not support monitoring beacon regions"); 
  26. }
  27. // Override point for customization after application launch. 
  28. return YES; 
  29. }
    • (void)_sendEnterLocalNotification
  30. {
  31. if (!_isInsideRegion)
  32. {
  33.   UILocalNotification *notice = [[UILocalNotification alloc] init]; 
  34.   notice.alertBody = @"Inside Estimote beacon region!"; 
  35.   notice.alertAction = @"Open"; 
  36.   [[UIApplication sharedApplication] scheduleLocalNotification:notice]; 
  37. }
  38. _isInsideRegion = YES;
  39. }
    • (void)_sendExitLocalNotification
  40. {
  41. if (_isInsideRegion)
  42. {
  43.   UILocalNotification *notice = [[UILocalNotification alloc] init]; 
  44.   notice.alertBody = @"Left Estimote beacon region!"; 
  45.   notice.alertAction = @"Open"; 
  46.   [[UIApplication sharedApplication] scheduleLocalNotification:notice]; 
  47. }
  48. _isInsideRegion = NO;
  49. }
    • (void)_updateUIForState:(CLRegionState)state
  50. {
  51. ViewController *vc = (ViewController *)self.window.rootViewController;
  52. if (state == CLRegionStateInside)
  53. {
  54.   vc.label.text = @"Inside"; 
  55. }
  56. else if (state == CLRegionStateOutside)
  57. {
  58.   vc.label.text = @"Outside"; 
  59. }
  60. else
  61. {
  62.   vc.label.text = @"Unknown"; 
  63. }
  64. }
  65. #pragma mark - CLLocationManagerDelegate
    • (void)locationManager:(CLLocationManager *)manager
  66. didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region 
  67. {
  68. // always update UI
  69. [self _updateUIForState:state];
  70. if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive)
  71. {
  72.   // don't send any notifications 
  73.   return; 
  74. }
  75.   if (state == CLRegionStateInside) 
  76.   { 
  77.      [self _sendEnterLocalNotification]; 
  78.   } 
  79.   else 
  80.   { 
  81.      [self _sendExitLocalNotification]; 
  82.   } 
  83. }
  84. @end Essentially, you just create a CLBeaconRegion and let the CLLocationManager object listen to it. For some devices, beacon monitoring will be unavailable, such as the lack of a BT4 chip, so you need to check isMonitoringAvailableForClass:.

Note: didDetermineState: will be called both when crossing the region boundary and after the requestStateForRegion: method. So you can do the monitoring work here and implement didEnterRegion and didExitRegion: to ensure that it will not interfere with users too much.

The rest of the code is used to send local notifications when the app is running in the background, and to avoid sending multiple identical messages to the same state continuously. When I tested, when I opened the soft beacon in the first example on the iPad, I always received the didEnterRegion: message immediately. After closing the beacon, you will receive the didExit message with a 43 second delay. So iOS does some filtering internally to avoid real-time triggering.

Backstage You will find that the above code runs very well when the app is running in the foreground, but will not continue to send/listen when the app enters the background.

In order to monitor the area in the background, you need to enable the "Location updates" background mode in the info.plist. "Acts as Bluetooth LE accessory" is used to make the soft beacon lasting. Xcode provides a very friendly UI for this.

Enabling iBeacon background modes The changes made here will eventually be reflected in the UIBackgroundModes in the info.plist file.

Adding accessory settings requires users to authorize Bluetooth file sharing. Note that the user may refuse or turn off authorization in the privacy settings.

A Mac integrated with a compatible BT4 chip can launch soft-beacon. CoreBluetooth can also be used on Mac since OS X 10.9. Macs manufactured after 2011 usually contain this chip. The only thing missing is CLBeaconRegion, but you can solve this problem if you build your own dictionary for broadcasting iBeacon. At this point, the last thing you need to know is that CoreBluetooth.framework is hidden in IOBluetooth.framework.

Matthew Robinson created the BeaconOSX sample to do this.

competition At the time of writing this article, Apple has not released an official iBeancon specification. When I asked the person in charge of Apple, he told me that they would inform me when they released it. So I can only hope that they will do so eventually. At the same time, some smart people are still running ahead and reverse engineering iBeacon.

Several iBeacon hardware has been released, and Estimote will soon feel the competition from them. Other companies I found after a cursory search are:

  1. FEASYCOM sells Arduino plug-in board (also called “shield”), the price is $29, and there is a Bluetooth Beacon.
  2. Kontakt.io sells beacons running on ordinary batteries that can be replaced manually, priced at $99 3, $149 5, and $279 10.
  3. GeoHopper uses USB as the mini plug for iBeacon: the price is $39.99 for 1 unit, $89.99 for 3 units, and 192.99 for 5 units.
  4. You can also (make one yourself with Raspberry Pi and Bluetooth LE adapter), the device is worth about $40, and the adapter is about $10.

Among the above companies, Estimote seems to serve the best.

USB power supply and replaceable batteries are not very necessary, and the low-power BTLE is said to last for 2 years. The waterproof rubber jacket and built-in stickers allow you to easily paste it anywhere without fear of being stolen and damaged.

However, the competition has never stopped. As more companies enter this hot field as always, the price in the next year will definitely be reduced by half or more. It is hoped that Estimote will remain competitive in price and will further reduce the price when the beacon can be mass-produced on the production line.

There are only two not-so-positive news. I personally think that custom SDKs should not be used as USPs to lock out users, and they do not plan to support custom UUIDs. Of course, perhaps for security reasons. Maybe they will understand eventually. Currently these things can be easily worked, and the rest of the "package" is also very valuable.

in conclusion Nothing can stop us from carrying forward iBeacon technology to make applications and services pay attention to user needs. If there is anything, it may be that Apple may update the still-secret iBeacon advertising package to include other values. But all the hardware devices I mentioned can also be upgraded to adjust the advertising value.

The only problem is the lack of imagination and low adoption rate in the slow seller and partner market. iBeacon promises to make entering traditional physical stores fun again. In this way, any such company will be well advertised to quickly adopt iBeacon, in this way to hook customers back to the physical store.

Small shops can run an iBeacon on the Mac or iPad they use for their POS system to avoid additional phone charges. This allows Passbook-based coupons or membership cards to automatically pop up when approaching the cashier.