所以我正在使用两个应用程序 . 一个充当中心,另一个是外围设备 . 可能有多个设备充当外围设备 . 当Central启动时,它开始扫描正在运行我称之为 UUIDService
的服务的外围设备 . 此服务有两个特征: vendorUUID
(读取)和 totalAmount
(写入) .
当外围设备发布时,它开始宣传 UUIDService
,其中 -[UIDevice identifierForVendor]
字符串为 vedorUUID
的值, nil
为 totalAmount.
在Central上,我有一个名为 BluetoothManager
的单例,它包含一个名为 connectedUsers
的可变数组,用于跟踪连接到中心的外围设备 . 这是一个 BTUser
对象的数组,它有两个属性:uuid(NSString)和periph(CBPeripheral) .
当Central发现外围设备时,它会创建用户对象并填写对 periph
的引用:
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
NSLog(@"Discovered periph advertising UUID Service");
BTUser* user = [[BTUser alloc] init];
user.periph = peripheral;
[_centralManager connectPeripheral:user.periph options:nil];
[_connectedUsers addObject:user];
NSLog(@"User periph: %@", user.periph.identifier);
}
这段代码有效 . _connectedUsers
现在包含一个带有 periph
的 BTUser
. 然后连接:
-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
NSLog(@"Connected periph: %@", peripheral.name);
BTUser* thisUser;
for (BTUser* user in _connectedUsers)
{
if ([user.periph.identifier isEqual: peripheral.identifier])
{
thisUser = user;
break;
}
}
thisUser.periph.delegate = self;
[thisUser.periph discoverServices:@[_uuidServiceUUID]];
}
我运行的是当我去使用外设的引用写入 totalAmount
时 .
-(void)initializePaymentWithUser:(BTUser*)user forAmount:(CGFloat)amount
{
_isListeningForUsers = NO;
[self stopScanningForUsers];
NSLog(@"disconnecting from all other users");
for (BTUser* u in _connectedUsers)
{
if (![u isEqual:user])
{
[u disconnectFromCentral:_centralManager];
}
}
CBService* uuidService = user.periph.services[0];
for (CBCharacteristic* cha in uuidService.characteristics)
{
if ([cha.UUID isEqual:_uuidServiceTotalAmountUUID])
{
NSLog(@"Writing total amount %.2f", amount);
NSData* data = [[NSString stringWithFormat:@"%.2f", amount] dataUsingEncoding:NSUTF8StringEncoding];
[user.periph writeValue:data
forCharacteristic:cha
type:CBCharacteristicWriteWithResponse];
break;
}
}
}
它使它成为写入值的块,并且 user.periph
仍然具有与最初连接时相同的 -[CBPeripheral identifier]
. 但是我收到了错误:
CoreBluetooth[WARNING] <CBPeripheral: 0x14ed28c0 identifier = B4CB35CC-2C78-7543-B083-E0B373EF66D0, Name = "iPhone", state = connected> is not a valid peripheral
外围设备从不调用 -peripheral:didWriteValueForCharacteristic:error
.
为了完成这个问题,这是来自外围设备的代码块,负责宣传 UUIDService
:
-(void)advertiseVendorUUID:(NSString*)uuid
paymentInitiatedBlock:(DOBluetoothPeripheralBlock)completion
{
_uuidService = [[CBMutableService alloc] initWithType: _uuidServiceUUID
primary:YES];
NSLog(@"Adding vendor id to characteristic: %@", uuid);
NSData* vendorData = [uuid dataUsingEncoding:NSUTF8StringEncoding];
_uuidServiceVendorUUIDChar = [[CBMutableCharacteristic alloc] initWithType:_uuidServiceVendorUUIDUUID
properties:CBCharacteristicPropertyRead
value:vendorData
permissions:CBAttributePermissionsReadable];
_uuidServiceTotalAmountChar = [[CBMutableCharacteristic alloc] initWithType:_uuidServiceTotalAmountUUID
properties:CBCharacteristicPropertyWrite
value:nil
permissions:CBAttributePermissionsWriteable];
_uuidService.characteristics = @[_uuidServiceVendorUUIDChar, _uuidServiceTotalAmountChar];
[_peripheralManager addService:_uuidService];
[_peripheralManager startAdvertising:@{CBAdvertisementDataServiceUUIDsKey: @[_uuidService.UUID],
CBAdvertisementDataLocalNameKey: @"UUID"}];
}