CBCentralManager scanForPeripheralsWithServices:nil没有返回任何结果

时间:2014-09-08 02:32:43

标签: ios objective-c bluetooth bluetooth-lowenergy

我正在尝试显示所有可用的BLE信标。我收到了一些Estimote和Kontakt.io信标,由于某种原因,下面的BLE扫描代码找不到它们。

我经历了与BLE发现相关的所有可能的SO问题,并且代码与其他地方完全相同。

App source code here

- (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");

}

3 个答案:

答案 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";
}