iOS Kingdom -- 智能開發(Bluetooth 篇一 -- Central)

Bluetooth
iOS 的藍牙分為中心設備(Central)和外設或邊設(Peripheral)。
Central
Central 處于主動地位,可主動發起搜索,連接,發送數據等動作,本篇主要講述的就是 iOS 藍牙做為 Central 時的使用方法。
在使用講解前,我們首先要理解兩個特有名詞——服務與特征。服務與特征對應的是 Peripheral 中的 CBServiceCBCharacteristic 。在一個外設中,服務可以有多個;在一個服務中,特征可以有多個。
Relationship

1、做為 Central 時的開發流程

1) 導入 CoreBluetooth/CoreBluetooth.h
2) 遵守 CBCentralManagerDelegate,CBPeripheralDelegate 協議
3) 建立中心角色
4) 掃描外設(discover)
5) 連接外設(connect)
6) 斷開連接
7) 獲取外設的服務與特征
8) 與外設交換數據(讀寫數據)
9) 必須實現centralManagerDidUpdateState:(CBCentral *)central這個require的方法

2、定義全局變量

{
        CBManagerCentral *_central;
        CBPeripheral *_periperal;
}

3、初始化中心變量

/** 初始化中心角色 */
dispatch_queue_t centralQueue = dispatch_queue_create(@“identify”,DISPATCH_QUEUE_SERIAL);
_central = [[CBManagerCentral alloc] initWithDelegate:self queue:centralQueue];

4、掃描外設

/*
掃描外設,services是外設服務的CBUUID,如果為空則掃描所有的外設
*/
[_central scanForPeripheralsWithServices:@[] option:options];

如果掃描到外設,則調用CBCentralManagerDelegate中的-(void)centralManager:didDescoverPeripheral:advertisementData:RSSI:

-(void)centralManager:(CBCentralManager *)central didDescoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:):(NSNumber *)RSSI{
        If(!peripheral || !peripheral.name || [peripheral.name     isEqualToString:@””]){
    return;
  }
if(“符合條件的peripheral”){
}
}

5、連接外設、查找外設服務與特征

/*
連接外設

options中可以設置一些連接設備的初始屬性鍵值如下
//對應NSNumber的bool值,設置當外設連接后是否彈出一個警告
NSString *const CBConnectPeripheralOptionNotifyOnConnectionKey;
//對應NSNumber的bool值,設置當外設斷開連接后是否彈出一個警告
NSString *const CBConnectPeripheralOptionNotifyOnDisconnectionKey;
//對應NSNumber的bool值,設置當外設暫停連接后是否彈出一個警告
NSString *const CBConnectPeripheralOptionNotifyOnNotificationKey;
*/
[_central connectPeripheral:_peripheral
                              options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES]
                                                                  forKey:CBConnectPeripheralOptionNotifyOnNotificationKey]];

連接成功后回調 CBCentralManagerDelegate- (void)centralManager:didConnectPeripheral: 方法

- (void)centralManager:(CBCentralManager *)central
  didConnectPeripheral:(CBPeripheral *)peripheral {
    peripheral.delegate = self;
    _peripheral = peripheral;

    // 查找外設服務,serviceUUIDs 為空時查找所有服務
    [peripheral discoverServices:@[]];
}

發現服務后調用 CBPeripheralDelegate- (void)peripheral:didDiscoverServices: 方法

- (void)peripheral:(CBPeripheral *)peripheral
didDiscoverServices:(NSError *)error {
    if (error) {
        return;
    }
    for (CBService *service in peripheral.services) {
        if ([service.UUID.UUIDString isEqualToString:@"符合條件的 UUIDString"]) {
            // 查詢服務對應的特征,characteristicUUIDs 為空時查詢所有特征
            [peripheral discoverCharacteristics:@[]
                                     forService:service];
        }
    }
}

發現特征后調用 CBPeripheralDelegate-(void)peripheral:didDiscoverCharacteristicsForService:error: 方法

-(void)peripheral:(CBPeripheral *)peripheral
didDiscoverCharacteristicsForService:(CBService *)service
            error:(NSError *)error {
    if (error) {
        return;
    }
    // 遍歷特征
    for (CBCharacteristic *cha in service.characteristics) {
        if ([cha.UUID.UUIDString isEqualToString:kR_UUID]) {
            // 特征判斷
         }
      }
}

特征的屬性 properties 有很多種,不同的屬性標明特征的用途。比如說,現有一特征的 properties 僅為 CBCharacteristicPropertyWrite ,那么這個特征只能用于 Central 端發送數據;而又有一特征的 properties 僅為 CBCharacteristicPropertyRead 那么這個特征只能用于 Central 讀數據

typedef NS_OPTIONS(NSUInteger, CBCharacteristicProperties) {
    CBCharacteristicPropertyBroadcast,                 //允許廣播特征
    CBCharacteristicPropertyRead,                      //可讀屬性
    CBCharacteristicPropertyWriteWithoutResponse,      //可寫并且接收回執
    CBCharacteristicPropertyWrite,                     //可寫屬性
    CBCharacteristicPropertyNotify,                    //可通知屬性
    CBCharacteristicPropertyIndicate,                  //可展現的特征值
    CBCharacteristicPropertyAuthenticatedSignedWrites, //允許簽名的特征值寫入
    CBCharacteristicPropertyExtendedProperties,
    CBCharacteristicPropertyNotifyEncryptionRequired,
    CBCharacteristicPropertyIndicateEncryptionRequired
};

6、斷開連接

[_centralr cancelPeripheralConnection:_peripheral];

斷開連接后調用 CBCentralManagerDelegate-(void)centralManager:didDisconnectPeripheral:error: 方法

7、發送數據

[_peripheral writeValue:data
              forCharacteristic:@"特征的屬性必須含有 CBCharacteristicPropertyWrite 或 CBCharacteristicPropertyWriteWithoutResponse"
                           type:@"視特征屬性而定"];

數據發送完成調用 CBPeripheralDelegate-(void)peripheral:didWriteValueForCharacteristic:error: 方法

- (void)peripheral:(CBPeripheral *)peripheral
didWriteValueForCharacteristic:(CBCharacteristic *)characteristic
             error:(nullable NSError *)error {
// 數據發送完成
}

8、讀數據

讀數據有兩種方法:
1、只讀一次數據,讀一次調用一次 - (void)readValueForCharacteristic: ,要確保調用在數據發出來之前,否則會讀不到數據

[_peripheral readValueForCharacteristic:@"特征要包含 CBCharacteristicPropertyRead 屬性"];

2、監聽數據,當數據開啟監聽后,只要有數據發送到客戶端,就會讀到數據

[_peripheral setNotifyValue:YES
          forCharacteristic:@"特征要包含 CBCharacteristicPropertyNotify 屬性"];

監聽開啟后會回調 CBPeripheralDelegate-(void)peripheral:didUpdateNotificationStateForCharacteristic:error: 方法

- (void)peripheral:(CBPeripheral *)peripheral
didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic
             error:(NSError *)error {
    if (error) {
        NSLog(@"監聽錯誤: %@ -- isNotifiying: %d",
                   error,characteristic.isNotifying);
        return;
    }
}

讀到數據回調 CBPeripheralDelegate-(void)peripheral:didUpdateValueForCharacteristic:error: 方法

- (void)peripheral:(CBPeripheral *)peripheral
didUpdateValueForCharacteristic:(nonnull CBCharacteristic *)characteristic
             error:(nullable NSError *)error {
    if (error) {
        NSLog(@"接收錯誤: %@",error);
        [self jmDisconnectWithError:error];
        return;
    }
}

這兩種方法須要特征的支持。也就是說,如果你的特征為 CBCharacteristicPropertyNotify 時才可以使用監聽讀數據

9、實現代理

- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
    // 狀態改變
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容