CoreBluetooth - 不发现服务
CoreBluetooth - not discovering services
我在使用 CoreBluetooth 时遇到了一个有趣的问题。我正在使用 iPhone 6 Plus 和 iPhone 4S 进行测试。两个设备都在 8.2
我在 class 的初始化方法中有以下设置:
_centralManager = [[CBCentralManager alloc] initWithDelegate:self
queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
options:@{CBCentralManagerOptionShowPowerAlertKey:[NSNumber numberWithBool:YES]}];
_peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self
queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
options:@{CBCentralManagerOptionShowPowerAlertKey:[NSNumber numberWithBool:YES]}];
//My characteristic and service setup is here and I finally add them to the peripheral:
[_peripheralManager addService:transferService];
[_peripheralManager addService:anotherService];
然后我开始外设管理广告和中央扫描如下:
[self.peripheralManager startAdvertising:@{CBAdvertisementDataLocalNameKey : @"My name",
CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:my_UUID]] }];
[self.centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:SAME_UUID_AS_ABOVE]]
options:nil];
此时委托方法:
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
被调用,广告数据字典与我在init方法中执行的设置一致,但是当我到达didDiscoverServices时,我看不到任何外设服务。我检查了控制台,指针是相同的(我将外围设备存储在 属性 中),UUID 也是如此。有趣的一点是,当我第一次发现外设时,名称是正确的,例如
<CBPeripheral: 0x1700f8500, identifier = xxxxx, name = My Name, state = disconnected>
但是当它到达 didDiscoverServices 时 - <CBPeripheral: 0x1700f8500, identifier =xxxx, name = iPhone, state = connected>
注意名字的不同。
我尝试将外围设备和中央设备设置为不同的队列,但没有结果。我的问题是,是否可以同时使用外设和中央设备,这会不会在发现服务时造成问题?
编辑: 另一个奇怪的地方。
1. 如果我重新启动两个设备,然后在广告和扫描调用之间在 6 Plus 上添加一个 sleep
调用,我可以看到来自 4S 的服务。
2. 如果我再次删除 sleep
和 运行 应用程序,我仍然可以看到该服务。然而,当我将 4S 插入 Xcode 并尝试从那里驱动流量时 - 我似乎无法得到它。 4S 的后续尝试也失败了。
问题是我在初始化之后立即将服务添加到外设管理器,即状态完成块没有办法。
与在外围设备完全初始化之前添加服务相关的类似问题。我发现在 peripheralManagerDidUpdateState: delegate 方法中添加服务是添加服务的好地方,因为这是在外围设备启动后立即调用的。
你应该检查:
(void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral {
if (self.manager.state >= CBPeripheralManagerStatePoweredOn) {
[self.manager addService:self.service];
}
else {
[self.manager removeService:self.service];
}
}
这将确保您在 BLE 打开时添加服务,在关闭时删除服务。
我在使用 CoreBluetooth 时遇到了一个有趣的问题。我正在使用 iPhone 6 Plus 和 iPhone 4S 进行测试。两个设备都在 8.2
我在 class 的初始化方法中有以下设置:
_centralManager = [[CBCentralManager alloc] initWithDelegate:self
queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
options:@{CBCentralManagerOptionShowPowerAlertKey:[NSNumber numberWithBool:YES]}];
_peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self
queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
options:@{CBCentralManagerOptionShowPowerAlertKey:[NSNumber numberWithBool:YES]}];
//My characteristic and service setup is here and I finally add them to the peripheral:
[_peripheralManager addService:transferService];
[_peripheralManager addService:anotherService];
然后我开始外设管理广告和中央扫描如下:
[self.peripheralManager startAdvertising:@{CBAdvertisementDataLocalNameKey : @"My name",
CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:my_UUID]] }];
[self.centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:SAME_UUID_AS_ABOVE]]
options:nil];
此时委托方法:
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
被调用,广告数据字典与我在init方法中执行的设置一致,但是当我到达didDiscoverServices时,我看不到任何外设服务。我检查了控制台,指针是相同的(我将外围设备存储在 属性 中),UUID 也是如此。有趣的一点是,当我第一次发现外设时,名称是正确的,例如
<CBPeripheral: 0x1700f8500, identifier = xxxxx, name = My Name, state = disconnected>
但是当它到达 didDiscoverServices 时 - <CBPeripheral: 0x1700f8500, identifier =xxxx, name = iPhone, state = connected>
注意名字的不同。
我尝试将外围设备和中央设备设置为不同的队列,但没有结果。我的问题是,是否可以同时使用外设和中央设备,这会不会在发现服务时造成问题?
编辑: 另一个奇怪的地方。
1. 如果我重新启动两个设备,然后在广告和扫描调用之间在 6 Plus 上添加一个 sleep
调用,我可以看到来自 4S 的服务。
2. 如果我再次删除 sleep
和 运行 应用程序,我仍然可以看到该服务。然而,当我将 4S 插入 Xcode 并尝试从那里驱动流量时 - 我似乎无法得到它。 4S 的后续尝试也失败了。
问题是我在初始化之后立即将服务添加到外设管理器,即状态完成块没有办法。
与在外围设备完全初始化之前添加服务相关的类似问题。我发现在 peripheralManagerDidUpdateState: delegate 方法中添加服务是添加服务的好地方,因为这是在外围设备启动后立即调用的。
你应该检查:
(void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral {
if (self.manager.state >= CBPeripheralManagerStatePoweredOn) {
[self.manager addService:self.service];
}
else {
[self.manager removeService:self.service];
}
}
这将确保您在 BLE 打开时添加服务,在关闭时删除服务。