我正在尝试显示所有可用的BLE信标。我收到了一些Estimote和Kontakt.io信标,由于某种原因,下面的BLE扫描代码找不到它们。
我经历了与BLE发现相关的所有可能的SO问题,并且代码与其他地方完全相同。
- (void)viewDidLoad {
[super viewDidLoad];
self.manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}
/*
Request CBCentralManager to scan for all available services
*/
- (void) startScan
{
NSLog(@"Start scanning");
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], CBCentralManagerScanOptionAllowDuplicatesKey, nil];
[self.manager scanForPeripheralsWithServices:nil options:options];
}
永远不会调用此委托方法
/*
Invoked when the central discovers bt peripheral while scanning.
*/
- (void) centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)aPeripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
NSLog(@"THIS NEVER GETS CALLED");
}
答案 0 :(得分:7)
iBeacon不作为外围设备访问 - 它们是信标。它们通过Core Location框架处理,而不是核心蓝牙框架。
可能由Core Bluetooth检测到的信标通告的供应商特定服务。
您的代码不会等到CBCentralManager
处于开机状态。我做了以下更改,它适用于iOS 7.1和iOS8 -
- (void)viewDidLoad {
[super viewDidLoad];
self.manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}
- (void) startScan
{
NSLog(@"Start scanning");
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], CBCentralManagerScanOptionAllowDuplicatesKey, nil];
[self.manager scanForPeripheralsWithServices:nil options:options];
}
- (BOOL) isLECapableHardware
{
NSString * state = nil;
switch ([self.manager state])
{
case CBCentralManagerStateUnsupported:
state = @"The platform/hardware doesn't support Bluetooth Low Energy.";
break;
case CBCentralManagerStateUnauthorized:
state = @"The app is not authorized to use Bluetooth Low Energy.";
break;
case CBCentralManagerStatePoweredOff:
state = @"Bluetooth is currently powered off.";
break;
case CBCentralManagerStatePoweredOn:
[self startScan];
return TRUE;
case CBCentralManagerStateUnknown:
default:
return FALSE;
}
NSLog(@"Central manager state: %@", state);
UIAlertView *alert = [[UIAlertView alloc] init];
[alert setMessage:state];
[alert addButtonWithTitle:@"OK"];
[alert show];
return FALSE;
}
答案 1 :(得分:3)
问题是由我测试的操作系统版本引起的。 我们只是说我测试的这个版本是4 + 4(因为它在NDA下)
显然,如果触发
,新版本将中止扫描[self.manager scanForPeripheralsWithServices:nil options:options];
之前
CBCentralManagerStatePoweredOn is ON
因此,只需在该状态之后开始扫描,这对我有用。
#pragma mark - CBCentralManager delegate methods
/*
Invoked whenever the central manager's state is updated.
*/
- (void) centralManagerDidUpdateState:(CBCentralManager *)central
{
[self isLECapableHardware]? NSLog(@"YES"):NSLog(@"NO");
}
- (BOOL) isLECapableHardware
{
NSString * state = nil;
switch ([self.manager state])
{
case CBCentralManagerStateUnsupported:
state = @"The platform/hardware doesn't support Bluetooth Low Energy.";
break;
case CBCentralManagerStateUnauthorized:
state = @"The app is not authorized to use Bluetooth Low Energy.";
break;
case CBCentralManagerStatePoweredOff:
state = @"Bluetooth is currently powered off.";
break;
case CBCentralManagerStatePoweredOn:
// --->该处
[self startScan];
return TRUE;
case CBCentralManagerStateUnknown:
default:
return FALSE;
}
return FALSE;
}
答案 2 :(得分:1)
我下载了你的代码,发现没有调用startScan。一旦我补充说它对我有用。我在日志记录中添加了一些细节:
- (void) centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)aPeripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
NSLog(@"Discovered %@ %@", aPeripheral, advertisementData);
}
我得到了这个输出:
2014-09-08 15:17:11.827 BTTest[4266:60b] New state 5
2014-09-08 15:17:11.830 BTTest[4266:60b] YES
2014-09-08 15:17:11.831 BTTest[4266:60b] Start scanning
2014-09-08 15:17:11.842 BTTest[4266:60b] CoreBluetooth[WARNING] <CBCentralManager: 0x17d6e5d0> is disabling duplicate filtering, but is using the default queue (main thread) for delegate events
2014-09-08 15:17:12.438 BTTest[4266:60b] per <CBPeripheral: 0x17d91220 identifier = C6E33BA0-F6E7-5830-0643-A47855AD27B9, Name = "(null)", state = disconnected> {
kCBAdvDataChannel = 37;
kCBAdvDataIsConnectable = 1;
}
2014-09-08 15:17:12.595 BTTest[4266:60b] per <CBPeripheral: 0x17d89b60 identifier = 4FF1E398-E24C-8739-A19B-9DF8A2A5493B, Name = "Flex", state = disconnected> {
kCBAdvDataChannel = 38;
kCBAdvDataIsConnectable = 1;
kCBAdvDataLocalName = Flex;
kCBAdvDataServiceData = {
"Device Information" = <0704>;
};
kCBAdvDataServiceUUIDs = (
"ADABFB00-6E7D-4601-BDA2-BFFAA68956BA"
);
kCBAdvDataTxPowerLevel = "-6";
}