I am developing an iPhone application and a Mac application that communicate with each other via Bluetooth LE. The iPhone is the central, and the Mac is the peripheral. I would like the iPhone application to be able to reconnect to the Mac application after a relaunch. Therefore, I save the UUID of the peripheral representing the Mac in NSUserDefaults, and then when the iPhone app launches, I call -[CBCentralManager retrievePeripheralsWithIdentifiers:]
, passing in the UUID. Although this method returns the peripheral, when I call -[CBCentralManager connectPeripheral:options:]
, the iPhone never reconnects to the Mac. According to this SO post, the problem is that the two devices need to be paired so that the UUID of the Mac is persistent. This brings me to my problem. I cannot for the life of me get the iPhone and the Mac to pair. According to this page of the Core Bluetooth Programming Guide, the way to require a paired connection is for the peripheral to set the characteristic's properties and permissions to the appropriate values. I quote:
You can ensure that only trusted devices have access to sensitive characteristic values by setting the appropriate characteristic properties and permissions. To continue the example above, to allow only trusted devices to retrieve a member’s email address, set the appropriate characteristic’s properties and permissions, like this:
emailCharacteristic = [[CBMutableCharacteristic alloc]
initWithType:emailCharacteristicUUID
properties:CBCharacteristicPropertyRead
| CBCharacteristicPropertyNotifyEncryptionRequired
value:nil permissions:CBAttributePermissionsReadEncryptionRequired];
However, this does not work. Even when I set the correct permissions and properties for the characteristic, the iPhone can still read/write to it without a pairing dialog being displayed. Elsewhere I am told that the way to initiate pairing is for the peripheral to reject a read/write request with an insufficient authentication error. According to this post,
To pair, you need to respond to a write request with an insufficient authentication error. For example, for an iOS peripheral you would write something like:
- (void)peripheralManager:(CBPeripheralManager *)peripheralManager didReceiveWriteRequests:(NSArray *)requests {
...
[peripheralManager respondToRequest:request withResult:CBATTErrorInsufficientAuthentication];
...
}
But this still doesn't work! When the Mac rejects the write request with an insufficient authentication error, the iPhone receives a -[CBPeripheralDelegate peripheral:didWriteValueForCharacteristic:error:]
callback with an error that says, "Authentication is insufficient." No pairing dialog. I have no idea what to do and am considering dropping Core Bluetooth altogether if I cannot get this to work. If you have any idea how to get this to work, please let me know.
From Apple DTS: "I have checked with other engineers here and we don’t believe that the pairing popup is possible between two iOS devices, but an iOS device and a BLE peripheral."
So, pairing popup happens only between a iOS/Mac app and a peripheral. rdar time.