> [Turning an iOS Device into an iBeacon](https://developer.apple.com/documentation/corelocation/turning_an_ios_device_into_an_ibeacon?language=occ)
学习如何在iOS设备上播放 iBeacon 信号。
### 第1节 概述
任何支持使用蓝牙低功耗共享数据的 iOS 设备都可以转换成 iBeacon 。使用 iOS 设备作为 iBeacon 的应用程序必须在前台运行。因此,对于应用程序来说,无论如何都要在前台运行该功能。对于其他类型的 iBeacon 实现,请使用来自第三方制造商的专用信标硬件。
要将 iOS 设备用作 iBeacon,请执行以下操作:
1. 为设备获取或生成一个128位的 UUID。
2. 创建一个包含 UUID 值的 CLBeaconRegion 对象,以及适合信标的 major 和 minor 值。
3. 使用 Core Bluetooth 框架来发送信标信息。
### 第2节 获取设备的 UUID
识别 iBeacon 的主要方式是来自其 UUID 。在部署一个或多个信标时,需要为每个信标分配一个 UUID,以将信标的用途传达给客户端。你定义的内容决定信标的用途。例如,百货商店可能为其所有已部署的信标使用相同的 UUID,或者每个商店可能会分配一个不同的 UUID。因为检测涉及使用区域监视来查找具有特定 UUID 的信标,所以使用更少的 UUID 更容易管理。
要为 iBeacon 部署创建一个新的 UUID ,请使用 uuidgen 命令行工具。打开终端,在命令行上输入 uuidgen,并按 Return。
该工具生成一个惟一的128位值,并将其格式化为一个ASCII字符串,该字符串被连字符分割断,如清单1所示。
###### 清单1 从命令行生成一个UUID
```
$ uuidgen
39ED98FF-2900-441A-802F-9C398FC199D2
```
### 第3节 配置 CLBeaconRegion 对象
使用 CLBeaconRegion 对象来配置信标的身份。可以使用信标区域生成一个信息字典,可以稍后通过蓝牙进行广播。清单2显示了如何创建一个信标区域对象并填充信息。
###### 清单2 配置信标的身份
```
//Swift
func createBeaconRegion() -> CLBeaconRegion? {
let proximityUUID = UUID(uuidString:
"39ED98FF-2900-441A-802F-9C398FC199D2")
let major : CLBeaconMajorValue = 100
let minor : CLBeaconMinorValue = 1
let beaconID = "com.example.myDeviceRegion"
return CLBeaconRegion(proximityUUID: proximityUUID!,
major: major, minor: minor, identifier: beaconID)
}
//Objective-C
NSUUID *proximityUUID = [[NSUUID alloc] initWithUUIDString:@"39ED98FF-2900-441A-802F-9C398FC199D2"];
CLBeaconMajorValue majorValue = 100;
CLBeaconMinorValue minorValue = 10;
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid major:majorValue minor:minorValue identifier:@"com.example.myDeviceRegion"];
```
UUID,major,minor 值是特定于 iBeacon 实施的。你决定这些值的含义,并决定检测信标的应用程序如何解读使用这些值。
### 第4节 通过蓝牙发送 iBeacon 广播
要从 iOS 设备上广播信标的身份,请使用 Core Bluetooth 框架将 iOS 设备配置为蓝牙外设。当配置为外设时,iOS 设备将使用蓝牙硬件向其他设备广播其信标信息。其他设备使用该信息来执行测距并检测其与 iOS 设备的距离。
将 Core Bluetooth 框架添加到 Xcode 工程中。在代码中,创建一个 [CBPeripheralManager](https://developer.apple.com/documentation/corebluetooth/cbperipheralmanager?language=objc) 对象并调用它 [startAdvertising:](https://developer.apple.com/documentation/corebluetooth/cbperipheralmanager/1393252-startadvertising?language=objc) 方法来开始广播信标数据。[startAdvertising:](https://developer.apple.com/documentation/corebluetooth/cbperipheralmanager/1393252-startadvertising?language=objc) 方法使用包含信标信息的字典作为参数。调用之前创建的 [CLBeaconRegion](https://developer.apple.com/documentation/corelocation/clbeaconregion?language=objc) 的 [peripheralDataWithMeasuredPower:](https://developer.apple.com/documentation/corelocation/clbeaconregion/1621494-peripheraldatawithmeasuredpower?language=objc) 方法,以获取包含与信标相关联的数据的字典。
###### 清单3 通过蓝牙广播设备
```
//Swift
func advertiseDevice(region : CLBeaconRegion) {
let peripheral = CBPeripheralManager(delegate: self, queue: nil)
let peripheralData = region.peripheralData(withMeasuredPower: nil)
peripheral.startAdvertising(((peripheralData as NSDictionary) as! [String : Any]))
}
//Objective-C
NSDictionary *peripheraData = [beaconRegion peripheralDataWithMeasuredPower:nil];
CBPeripheralManager *peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil];
[peripheralManager startAdvertising:peripheraData];
```
调用 [peripheralDataWithMeasuredPower:](https://developer.apple.com/documentation/corelocation/clbeaconregion/1621494-peripheraldatawithmeasuredpower?language=objc) 方法获取数据字典时,通常会传递 nil 来指定与 iOS 设备关联的默认接收信号强度指示(RSSI)值。此参数表示从离设备一米远处测得的信号强度(以分贝为单位)。如果需要在某些环境中校准设备以获得更好的测距性能,则可以指定自定义值。
在创建外围管理器对象时,它会调用其委托对象的 [peripheralManagerDidUpdateState:](https://developer.apple.com/documentation/corebluetooth/cbperipheralmanagerdelegate/1393271-peripheralmanagerdidupdatestate?language=objc) 方法。必须实施此代表方法,以确保在 iOS 设备上支持并使用 BLE 。
> 重要提示
> 在将应用作为一个 iBeacon 进行广播之后,应用必须继续在前台运行,以播放所需的蓝牙信号。如果用户退出应用,系统就会停止在蓝牙设备上做广播。
在测距期间,可能会有一段短暂的时间,Core Location 为同一个 iOS 设备创建两个 [CLBeacon](https://developer.apple.com/documentation/corelocation/clbeacon?language=objc) 对象。出现这种情况的原因是 iOS 定期更改设备的 Bluetooth 标识符以保护用户的隐私,一个信标代表旧标识符,一个信标代表新标识符。在标识符更改的2秒内,具有旧标识符的信标将其接近度属性设置为 [CLProximityUnknown](https://developer.apple.com/documentation/corelocation/clproximity/clproximityunknown?language=objc)。在10秒钟之内,旧的标识符不再被报告。