CoreBluetooth 广告错误

CoreBluetooth advertisement error

我在尝试公布某些服务数据时遇到一个奇怪的错误。

func locationManager(manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], inRegion region: CLBeaconRegion) {
    if let beacon = beacons.first, username = NSUserDefaults.standardUserDefaults().objectForKey("username") {
        var major = beacon.major.integerValue
        var minor = beacon.minor.integerValue

        let advertismentData:[String:AnyObject] = [
            CBAdvertisementDataServiceUUIDsKey:[AppDelegate.MajorUUID, AppDelegate.MinorUUID, AppDelegate.IdentifierUUID],
            CBAdvertisementDataServiceDataKey:[AppDelegate.MajorUUID: NSData(bytes: &major, length: sizeof(Int)), AppDelegate.MinorUUID: NSData(bytes: &minor, length: sizeof(Int)), AppDelegate.IdentifierUUID: username.dataUsingEncoding(NSUTF8StringEncoding)]
        ]
        peripheralManger?.startAdvertising(advertismentData)
        manager.stopRangingBeaconsInRegion(region)
    }
}

传递开始广告时出现以下错误:

2015-10-09 11:17:05.563 BeConvo[280:21134] -[CBUUID UTF8String]: unrecognized selector sent to instance 0x13dd5b420 2015-10-09 11:17:05.564 BeConvo[280:21134] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[CBUUID UTF8String]: unrecognized selector sent to instance 0x13dd5b420' * First throw call stack: (0x185364f5c 0x199f5bf80 0x18536bc6c 0x185368c14 0x18526cdcc 0x184fe56b4 0x185361f00 0x184fe4634 0x184fe58a8 0x184fe56d8 0x185361f00 0x184fe4634 0x184fe44dc 0x184fe4704 0x184fe47e8 0x184fe6104 0x184fe7190 0x1000eb9a4 0x1000ebae0 0x185af5f04 0x185af0b14 0x185aeaef4 0x18531c48c 0x18531bdc4 0x18531a20c 0x185248dc0 0x19039c088 0x18a922f44 0x1000ec328 0x19a7868b8) libc++abi.dylib: terminating with uncaught exception of type NSException

如果我删除 ServiceDataKey 或删除字典的内容,则广告成功。

func locationManager(manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], inRegion region: CLBeaconRegion) {
    if let beacon = beacons.first, username = NSUserDefaults.standardUserDefaults().objectForKey("username") {
        var major = beacon.major.integerValue
        var minor = beacon.minor.integerValue

        let advertismentData:[String:AnyObject] = [
            CBAdvertisementDataServiceUUIDsKey:[AppDelegate.MajorUUID, AppDelegate.MinorUUID, AppDelegate.IdentifierUUID],
            CBAdvertisementDataServiceDataKey:[]
        ]
        peripheralManger?.startAdvertising(advertismentData)
        manager.stopRangingBeaconsInRegion(region)
    }
}

我已经尝试了 key/value 对中的每一对,看它是否是特定的一对,但任何组合中的任何一个都会导致错误发生。

有人有什么想法吗?

感谢您的帮助。

如果您想以 iBeacon 的形式投放广告,使用 CLBeaconRegionperipheralDataWithMeasuredPower 方法会更容易且不易出错,该方法会自动为您生成适当的广告数据。下面的示例代码片段:

let region = CLBeaconRegion(proximityUUID: beacon.proximityUUID,
                            major: beacon.major, minor: beacon.minor,
                            identifier: "iOS beacon")
let advertisementData = region.peripheralDataWithMeasuredPower(nil)
peripheralManger?.startAdvertising(advertisementData)

不幸的是,CBAdvertisementDataServiceDataKey 在 iOS 上只读。虽然您可以在发现外围设备时使用它来读取服务数据,但不能使用它来使用 CBPeriperalManager 传输服务数据。有关详细信息,请参阅此处:

如果你想传输一个 iBeacon 数据包,你可以使用 region.peripheralDataWithMeasuredPower(nil) 正如@heypiotr 在他的回答中所建议的那样。

为了便于理解,请注意,iBeacon 广告是制造商蓝牙广告,而不是服务广告。因此,即使显示的技术确实有效,也没有理由像示例中所示那样填充 CBAdvertisementDataServiceUUIDsKey。发送服务广告不会触发 iBeacon 接收器。