CoreBluetooth.framework(二)

6672 ワード

1、スキャンでサービスを探す
//  iOS                  
self.manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:@{CBCentralManagerOptionShowPowerAlertKey:@(NO)}];

まず周辺機器をスキャンする
 //                                           ,                ,           , YES     
    [self.manager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:_serviceUUID]] options:@{CBCentralManagerScanOptionAllowDuplicatesKey : [NSNumber numberWithBool:YES]}];

scanForPeripheralsWithServices:メソッドは、パラメータとしてサービス配列を使用し、周辺地域で放送されているこれらのサービスの周辺デバイスをスキャンします.Nilをパラメータとして使用すると、使用可能なすべての周辺デバイスがスキャンされますが、これは遅いです.
CBCentralManagerというクラスには、発見した周辺機器、サービス、サービスの特性、数値の変化を通知するCBCentralManagerDelegateという依頼があります.Bluetoothが開いていない場合は、CBCentralManagerDelegateのcentralManagerDidUpdateStateメソッドでコールバックが受信され、このメソッドも周辺デバイスのスキャンを開始します.
#pragma mark - CBCentralManagerDelegate
/**
 *                  
 */
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
    switch (central.state) {
        case CBManagerStatePoweredOn:
            //           GCD
        case CBManagerStateResetting:
        {
            dispatch_async(dispatch_get_main_queue(), ^{
                
                if (self.connectState == DoorOpenStateScanning)
                    [self starScanPeripheral];
            });
            
        }
            break;
            //
        case CBManagerStateUnknown:
        {
        }
            break;
        default:
        {
            [self stopConnect];
        }
            break;
    }
}


周辺機器を見つけたら、CBCentralManagerDelegateのdidDiscoverPeripheral:メソッドで周辺機器の詳細を取得できます.
2.接続デバイスが周辺デバイスを見つけた後、次のステップは周辺デバイスを接続し、彼が提供したサービスを発見することです.
/**
 *    
 */
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
//      
//      
    [central connectPeripheral:peripheral options:nil];
}

ARCコンパイラは周辺デバイスオブジェクトを解放し、接続できないため、周辺デバイスに接続する前に保持する必要があります.配列に追加して保持できます.
3.周辺機器の識別子を知っている場合は、この方法でスキャンできます.この方法はiOS 7が加入したものです.まず周辺デバイスのリストを配列に追加し、この配列を保存し、デバイスをスキャンするたびに既知の周辺デバイスに接続しようとするのが良い習慣です.スキャンは比較的消費電力がかかり、避けるべきです.周辺機器のポインタを手に入れると、直接接続できます.
- (NSArray *)retrievePeripheralsWithIdentifiers:(NSArray *)identifiers NS_AVAILABLE(NA, 7_0);

4.サービスが接続を確立する試みが成功するか失敗するかを発見し、成功すればこの依頼方法を呼び出す.次のステップは、周辺機器が提供するサービスを発見することです.
/**
 *           ,      
 *peripheral               ,                 
 * NSLog(@">>>      (%@)   -  ",peripheral.name);
 */
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
    self.peripheral = peripheral;
    _isConnect = YES;
    self.connectState = DoorOpenStateConnected;
    //   peripheral  CBPeripheralDelegate
    [peripheral setDelegate:self];  //    
    //    Services,        
    [peripheral discoverServices:nil];
}

周辺機器が提供するサービスリストは、CBPeripheralDelegateの依頼方法によって通知され、周辺機器のサービス属性からサービスリストを取得することができる.
#pragma mark - CBPeripheralDelegate

/**
 *      Services,        
 *                 (           peripheral services)
 */
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
    if (error)
    {
        if ([self.delegate respondsToSelector:@selector(openDoorFailed:error:)]) {
            [self.delegate openDoorFailed:self.curDoor error:error];
        }
        [self stopConnect];
        return;
    }
    
    BOOL bFind = NO;
    for (CBService *service in peripheral.services)
    {
        //    
        if ([service.UUID.UUIDString isEqualToString:@"FFF0"])
        {
             NSLog(@"====%@------%@+++++++",service.UUID.UUIDString,self.peripheral.identifier);
             // characteristicUUIDs :            ( nil,       )
            _service = service;
            [peripheral discoverCharacteristics:nil forService:service];
            bFind = YES;
            break;
        }
    }
    if (!bFind) {
        [self stopConnect];
        if ([self.delegate respondsToSelector:@selector(openDoorFailed:error:)]) {
            NSError *error1 = [NSError errorWithDomain:@"openDoorFailed" code:LeEGNotDiscoverServices userInfo:@{NSLocalizedDescriptionKey:@"          "}];
            [self.delegate openDoorFailed:self.curDoor error:error1];
        }
    }
}


5.フィーチャー特性の発見:サービスのオン/オフ、またはサービスの現在の値の読み取り.発見された特性を返す依頼方法.
/**
 *               
 */
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(nullable NSError *)error {

     NSLog(@"         ");
    
    for (CBCharacteristic *characteristic in service.characteristics)
    {
         NSLog(@"====%@------+",characteristic.UUID.UUIDString);
        //    
        if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"FFF1"]]) {
            //          NSLog(@"  :%@",characteristic);//    
            //     ,         
            [self.peripheral setNotifyValue:YES forCharacteristic:characteristic];
            
            self.charWrite = characteristic;
        } else if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"FFF4"]]) {
            [self.peripheral setNotifyValue:YES forCharacteristic:characteristic];
            self.charRead = characteristic;
            
        }
    }
    if (self.charRead && self.charWrite) {
        if (![self need3DES:self.curDoor]) {
            [self sendOpenDoorCommand];
        } else {
            //     ,                
            [self WriteValue:@"BB"];
            self.connectState = DoorOpenStateWaitKey;
        }
    } else {
        if ([self.delegate respondsToSelector:@selector(openDoorFailed:error:)]) {
            NSError *error1 = [NSError errorWithDomain:@"openDoorFailed" code:LeEGNotDiscoverCharacteristics userInfo:@{NSLocalizedDescriptionKey:@"     "}];
            [self.delegate openDoorFailed:self.curDoor error:error1];
        }
        [self stopConnect];
        return;
    }

}


次の方法では、データの更新や変更のメッセージを受信します.
/**
 *     ,       :didUpdateValueForCharacteristic  
 */
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error {}

数値変化はNSData形式で送られてきました.状況に応じて実際のデータを変換する必要がある.
6.独自の周辺機器を作成する.frameworkはiOS 7にCBPeripheralManagerとCBCentralの2つのクラスを追加しました.