iOS开发——为什么我的scanForPeripheralsWithServices根本不起作用

在iOS蓝牙应用开发中,作者遇到scanForPeripheralsWithServices未发现蓝牙外围设备的问题。问题在于必须在centralManager的state为PoweredOn时执行scan操作。解决方案是在centralManagerDidUpdateState回调中进行扫描,而非在viewDidLoad中。此问题在苹果官方示例中未明确提及,可能误导开发者。

这次真的是被苹果坑了,最近不是在开发iOS蓝牙应用嘛,一开始就TM卡壳了,真是@#$&%*)。我之前翻译的文章中说,第一步是要发现广播的蓝牙外围设备,但就是这简简单单的第一步,走得并没那么顺利。

问题描述

那么问题是什么呢?scanForPeripheralsWithServices是调用了,周围辣么多的蓝牙外围,就是发现不了啊!本该回调的callback函数didDiscoverPeripheral:advertisementData:RSSI:根本就没反应啊!源代码是这样的:

@interface ViewController () <CBCentralManagerDelegate, CBPeripheralDelegate>

@property (strong, nonatomic) CBCentralManager* manager;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

     self.manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
     [self startScan];
}


/*
 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");

}

/* centralManagerDidUpdateState: is a required method of CBCentralManagerDelegate */
- (void) centralManagerDidUpdateState:(CBCentralManager*)central
{
    switch(central.state) {
        case CBCentralManagerStatePoweredOn:
            NSLog(@"The central manager is powered on and ready.");
            break;
        default:
            break;
    }
}

@end

一点反应没有,坑爹!说好的彼此相爱呢?

解决方案

Google了下,果然有不少我这样的冤大头。大家一致谴责了苹果不负责任乱改代码却不加说明的态度,进而拿出了解决方案:

貌似这一版CoreBluetooth必须在确定centralManager的state为PoweredOn后,才能执行scan操作。于是乎,不要在viewDidLoad里执行startScan啦,放在centralManagerDidUpdateStatecase CBCentralManagerStatePoweredOn 后面就可以了,像这样:

- (void)viewDidLoad {
     [super viewDidLoad];
     self.manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
     // [self startScan]; //删除这一行
     }
- (void) centralManagerDidUpdateState:(CBCentralManager*)central
{
    switch(central.state) {
        case CBCentralManagerStatePoweredOn:
            NSLog(@"The central manager is powered on and ready.");
            [self startScan]; //加到这里这里这里!
            break;
        default:
            break;
    }
}

嗯,运行下,是不是终于didDiscoverPeripheral了?感激涕零。。。个屁啊!坑爹不是这么坑的,气死我了,苹果官方给的sample里也没提到这事儿啊,还是在viewDidLoad里面扫描得很带劲啊,根本没提这茬。

总结

呼——平心静气地总结一下,iOS 8里面(其他没试过),如果你要scanForPeripheralsWithServices的话,必须要放在centralManagerDidUpdateState的CBCentralManagerStatePoweredOn下面。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值