我这样扫描我的外围设备:
NSDictionary *scanOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO]
forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
// Scan for peripherals with given UUID
[cm scanForPeripheralsWithServices:[NSArray arrayWithObject:HeliController.serviceUUID] options:scanOptions]
没问题,我找到了外设并能够连接到它。正如你所看到的,我给它CBCentralManagerScanOptionAllowDuplicatesKey
和bool NO
,不允许多个外设,但有时didDiscoverPeripheral
回调会触发两次。
- (void) centralManager:(CBCentralManager *)central
didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData
RSSI:(NSNumber *)RSSI
{
if(!discovered){
discovered = YES;
NSLog(@"Discovered");
[cm stopScan];
[scanButton setTitle:@"Connect" forState:UIControlStateNormal];
}
else if(discovered){
discovered = YES
NSLog(@"Already discovered");
}
}
有时我会收到
Discovered
Already discovered
作为控制台中的输出,大多数时候只显示Discovered
消息。
在我的外围代理中,我首先发现服务,然后调用[peripheral discoverCharacteristics
,回调总是发生:
- (void) peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
NSLog(@"Did discover characteristic for service %@", [service.peripheral UUID]);
for(CBCharacteristic *c in [service characteristics]){
// We never get here when peripheral is discovered twice
if([[c UUID] isEqual:myCharacteristicUUID]){
NSLog(@"Found characteristic");
self.throttleCharacteristic = c;
}
}
当didDiscoverPeripheral
出现两次时,在这种方法中,即使peripheral
不是(UUID,名称仍然正确),service
也会变成nil
。
重新启动手机或重置网络设置可暂时解决此问题。
我真的需要解决这个问题!感谢
设备在发布广告时可能会返回额外的数据。这些可能以不同的包到达,在不同的时间到达。在这种情况下,当最初看到设备时,首先调用didDiscoverPeripheral,然后当其他信息可用时再次调用。
CBCentralManagerScanOptionAllowDuplicatesKey不同。当设备再次广告时,它会告诉CoreBluetooth您是否希望接收重复的结果。它不会阻止对同一发现序列多次调用didDiscoverPeripheral;它防止重复发现序列。
来源:http://lists.apple.com/archives/bluetooth-dev/2012/Apr/msg00047.html(苹果公司蓝牙开发代表)。
我不认为这个参数会起到你认为的作用。从它在健康温度计等苹果样品中的使用情况来看,我的理解是,打开此标志可以发现具有相同UUID的多个不同外围设备。例如,如果你想写一个应用程序,在同一个房间里查看四个不同的温度计,并找到所有的温度计,你需要这个参数,这样扫描就不会在找到第一个温度计后停止。
在他们的代码中,苹果避免了类似这样的重复:
NSMutableArray *peripherals = [self mutableArrayValueForKey:@"thermometers"];
if( ![self.thermometers containsObject:peripheral] )
[peripherals addObject:peripheral];
如果该设备已存在于阵列中,则不会再次添加。
如果文档在这一点上更清晰,那就太好了。我承认我是根据这个参数在上下文中的使用方式来猜测的。