苹果蓝牙sdk没有回调问题

最近也就小米手环蓝牙协议, android版本完成了一小半. 开始尝试ios/mac版本

发现一个挺坑的问题, 一个简单的测试程序一般这么写:


@interface AppDelegate()
@property (atomic,strong) BlutoothIO* io;

@end

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    CBCentralManager* central = [[CBCentralManager alloc]initWithDelegate:self queue:nil options:nil];
    
}

- (void)applicationWillTerminate:(NSNotification *)aNotification {
    
}

- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
    NSLog(@"centralManagerDidUpdateState:%ld",central.state);
    if (central.state == CBCentralManagerStatePoweredOn) {
        NSLog(@"scanForPeripheralsWithServices");
        [central scanForPeripheralsWithServices:nil
                                        options:nil];
    }
}

@end

然后你会发现, 什么都没发生, centralManagerDidUpdateState函数完全没有被调用. 各种google, 才知道结果;

为啥? 因为object-c会自动回收, applicationDidFinishLaunching 里的 central 在函数结束后就被析构掉了, 自然也就不会有回调发生!

同理,修改之后的程序:

- (id)init
{
    if ((self = [super init]))
    {
        self.central = [[CBCentralManager alloc]initWithDelegate:self queue:nil options:nil];
    }
    return self;
}

- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
    NSLog(@"centralManagerDidUpdateState:%ld",central.state);
    if (central.state == CBCentralManagerStatePoweredOn) {
        NSLog(@"scanForPeripheralsWithServices");
        [central scanForPeripheralsWithServices:nil
                                        options:nil];
        
    }
}

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
    
    NSLog(@"Peripheral connected: %@",peripheral.name);
    [peripheral discoverServices:nil];
}

- (void)centralManager:(CBCentralManager *)central
didFailToConnectPeripheral:(CBPeripheral *)peripheral
                 error:(NSError *)error{
    NSLog(@"didFailToConnectPeripheral: %@, error:%@",peripheral.name,error);
}

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *) advertisementData
                  RSSI:(NSNumber *)RSSI {
    
    NSLog(@"Discovered %@", peripheral.name);
    [central stopScan];
    
    peripheral.delegate = self;
    [central connectPeripheral:peripheral options:nil];
}

- (void)peripheralDidUpdateRSSI:(CBPeripheral *)peripheral
                          error:(NSError *)error{
    NSLog(@"peripheralDidUpdateRSSI %@", peripheral.RSSI);

}

didDiscoverPeripheral回调之后, 发现了设备peripheral, 然后去做connectPeripheral, 不管didConnectPeripheral还是didFailToConnectPeripheral也都没有被回调, 为啥?

因为didDiscoverPeripheral函数中传进来的peripheral 再函数之后同样被释放了!

解决办法就是找个数组之类的什么东西hold住他, 比如:

@property (strong,nonatomic) NSMutableArray *peripherals;
-(void) centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
    [self.peripherals addObject:peripheral];
    [central connectPeripheral:peripheral options:nil];
}

吐槽!! 第一个问题central没有hold住还好理解, 你CBCentralManagerDiscoverPeripheral了之后传过来的peripheral,你CBCentralManager都不hold住, 还做什么Manager…

参考: