iOS藍芽開發(二):iOS 藍芽4.0中心模式 代碼實現

來源:互聯網
上載者:User

上一篇簡單介紹了藍芽的部分基礎知識,詳細的東西大家可以去github上搜babyBluetooth,裡面有一些學習資料 iOS串連外設的流程 建立中心管理者 掃描外設 discoverPeripheral 串連外設 connectPeripheral 掃描外設中的服務和特徵 discoverServices discoverCharacteristics
擷取外設的services 擷取外設service中的characteristics 擷取characteristic的值value、descriptor的value 與外設做資料互動 write、read 訂閱characteristic的通知notify 中斷連線 disconnected 實現步驟

1、匯入CoreBluetooth標頭檔,建立中心管理類,設定代理

#import <CoreBluetooth/CoreBluetooth.h>@interface ViewController : UIViewController<CBCentralManagerDelegate>@interface ViewController (){    //系統藍牙裝置管理對象,可以把他理解為主裝置,通過他,可以去掃描和連結外設    CBCentralManager *manager;    //用於儲存被發現裝置    NSMutableArray *peripherals;}- (void)viewDidLoad {    [super viewDidLoad];    /*     設定主裝置的委託,CBCentralManagerDelegate        必須實現的:        - (void)centralManagerDidUpdateState:(CBCentralManager *)central;//主裝置狀態改變的委託,在初始化CBCentralManager的適合會開啟裝置,只有當裝置正確開啟後才能使用        其他選擇實現的委託中比較重要的:        - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI; //找到外設的委託        - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral;//串連外設成功的委託        - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;//外設串連失敗的委託        - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;//斷開外設的委託    */     //初始化並設定委託和線程隊列,最好一個線程的參數可以為nil,預設會就main線程     manager = [[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_main_queue()];

2、掃描外設(discover),掃描外設的方法我們放在centralManager成功開啟的委託中,因為只有裝置成功開啟,才能開始掃描,否則會報錯。
所以當重新串連外設時,都不會成功,因為states還沒開啟;一般自己寫藍芽,這個地方要處理一下,串連的時候判斷一下,還未開啟就重連,一直等到PoweredOn

-(void)centralManagerDidUpdateState:(CBCentralManager *)central{        switch (central.state) {            case CBCentralManagerStateUnknown:                NSLog(@">>>CBCentralManagerStateUnknown");                break;            case CBCentralManagerStateResetting:                NSLog(@">>>CBCentralManagerStateResetting");                break;            case CBCentralManagerStateUnsupported:                NSLog(@">>>CBCentralManagerStateUnsupported");                break;            case CBCentralManagerStateUnauthorized:                NSLog(@">>>CBCentralManagerStateUnauthorized");                break;            case CBCentralManagerStatePoweredOff:                NSLog(@">>>CBCentralManagerStatePoweredOff");                break;            case CBCentralManagerStatePoweredOn:                NSLog(@">>>CBCentralManagerStatePoweredOn");                //開始掃描周圍的外設                /*                 第一個參數nil就是掃描周圍所有的外設,掃描到外設後會進入                      - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI;                 */                [manager scanForPeripheralsWithServices:nil options:nil];                break;            default:                break;        }    }    //掃描到裝置會進入方法    -(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{        NSLog(@"當掃描到裝置:%@",peripheral.name);        //接下來可以串連裝置    }

3、串連外設
有一點注意,找到的peripheral必須被持有:(比如添加到數組、賦值給另一個被持有的變數),否則CBCentralManager中也不會儲存這個peripheral,那麼CBPeripheralDelegate中的方法也不會被調用

    //掃描到裝置會進入方法    -(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{        //接下串連我們的測試裝置,如果你沒有裝置,可以下載一個app叫lightbule的app去類比一個裝置        //這裡自己去設定下串連規則,我設定的是P開頭的裝置               if ([peripheral.name hasPrefix:@"P"]){               /*                   一個主裝置最多能連7個外設,每個外設最多隻能給一個主裝置串連,串連成功,失敗,斷開會進入各自的委託                - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral;//串連外設成功的委託                - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;//外設串連失敗的委託                - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;//斷開外設的委託                */                //找到的裝置必須持有它,否則CBCentralManager中也不會儲存peripheral,那麼CBPeripheralDelegate中的方法也不會被調用。。                [peripherals addObject:peripheral];                //串連裝置               [manager connectPeripheral:peripheral options:nil];           }    }    //串連到Peripherals-成功    - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral    {        NSLog(@">>>串連到名稱為(%@)的裝置-成功",peripheral.name);    }    //串連到Peripherals-失敗    -(void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error    {        NSLog(@">>>串連到名稱為(%@)的裝置-失敗,原因:%@",[peripheral name],[error localizedDescription]);    }    //Peripherals中斷連線    - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{        NSLog(@">>>外設串連中斷連線 %@: %@\n", [peripheral name], [error localizedDescription]);    }

4、掃描外設中的服務和特徵(discover)
裝置串連成功後,就可以掃描裝置的服務了,同樣是通過委託形式,掃描到結果後會進入委託方法。但是這個委託已經不再是主裝置的委託(CBCentralManagerDelegate),而是外設的委託(CBPeripheralDelegate),這個委託包含了主裝置與外設互動的許多 回叫方法,包括擷取services,擷取characteristics,擷取characteristics的值,擷取characteristics的Descriptor,和Descriptor的值,寫資料,讀rssi,用通知的方式訂閱資料等等。

5、擷取外設的services

    //串連到Peripherals-成功    - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral    {        NSLog(@">>>串連到名稱為(%@)的裝置-成功",peripheral.name);        //設定的peripheral委託CBPeripheralDelegate        //@interface ViewController : UIViewController<CBCentralManagerDelegate,CBPeripheralDelegate>        [peripheral setDelegate:self];        //掃描外設Services,成功後會進入方法:-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{        [peripheral discoverServices:nil];    }    //掃描到Services    -(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{        //  NSLog(@">>>掃描到服務:%@",peripheral.services);        if (error)        {            NSLog(@">>>Discovered services for %@ with error: %@", peripheral.name, [error localizedDescription]);            return;        }        for (CBService *service in peripheral.services) {                         NSLog(@"%@",service.UUID);                         //掃描每個service的Characteristics,掃描到後會進入方法: -(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error                         [peripheral discoverCharacteristics:nil forService:service];                     }    }

6、擷取外設的Characteristics,擷取Characteristics的值,擷取Characteristics的Descriptor和Descriptor的值

    //掃描到Characteristics -(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{     if (error)     {         NSLog(@"error Discovered characteristics for %@ with error: %@", service.UUID, [error localizedDescription]);         return;     }     for (CBCharacteristic *characteristic in service.characteristics)     {         NSLog(@"service:%@ 的 Characteristic: %@",service.UUID,characteristic.UUID);     }     //擷取Characteristic的值,讀到資料會進入方法:-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error     for (CBCharacteristic *characteristic in service.characteristics){         {             [peripheral readValueForCharacteristic:characteristic];         }     }     //搜尋Characteristic的Descriptors,讀到資料會進入方法:-(void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error     for (CBCharacteristic *characteristic in service.characteristics){         [peripheral discoverDescriptorsForCharacteristic:characteristic];     } }//擷取的charateristic的值-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{    //列印出characteristic的UUID和值    //!注意,value的類型是NSData,具體開發時,會根據外設協議制定的方式去解析資料    NSLog(@"characteristic uuid:%@  value:%@",characteristic.UUID,characteristic.value);}//搜尋到Characteristic的Descriptors-(void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{    //列印出Characteristic和他的Descriptors     NSLog(@"characteristic uuid:%@",characteristic.UUID);    for (CBDescriptor *d in characteristic.descriptors) {        NSLog(@"Descriptor uuid:%@",d.UUID);    }}//擷取到Descriptors的值-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForDescriptor:(CBDescriptor *)descriptor error:(NSError *)error{    //列印出DescriptorsUUID 和value    //這個descriptor都是對於characteristic的描述,一般都是字串,所以這裡我們轉換成字串去解析    NSLog(@"characteristic uuid:%@  value:%@",[NSString stringWithFormat:@"%@",descriptor.UUID],descriptor.value);}   

7、把資料寫到Characteristic中

//寫資料-(void)writeCharacteristic:(CBPeripheral *)peripheral            characteristic:(CBCharacteristic *)characteristic                     value:(NSData *)value{    //列印出 characteristic 的許可權,可以看到有很多種,這是一個NS_OPTIONS,就是可以同時用於好幾個值,常見的有read,write,notify,indicate,知知道這幾個基本就夠用了,前連個是讀寫權限,後兩個都是通知,兩種不同的通知方式。    /*     typedef NS_OPTIONS(NSUInteger, CBCharacteristicProperties) {     CBCharacteristicPropertyBroadcast                                              = 0x01,     CBCharacteristicPropertyRead                                                   = 0x02,     CBCharacteristicPropertyWriteWithoutResponse                                   = 0x04,     CBCharacteristicPropertyWrite                                                  = 0x08,     CBCharacteristicPropertyNotify                                                 = 0x10,     CBCharacteristicPropertyIndicate                                               = 0x20,     CBCharacteristicPropertyAuthenticatedSignedWrites                              = 0x40,     CBCharacteristicPropertyExtendedProperties                                     = 0x80,     CBCharacteristicPropertyNotifyEncryptionRequired NS_ENUM_AVAILABLE(NA, 6_0)        = 0x100,     CBCharacteristicPropertyIndicateEncryptionRequired NS_ENUM_AVAILABLE(NA, 6_0)  = 0x200     };     */    NSLog(@"%lu", (unsigned long)characteristic.properties);    //只有 characteristic.properties 有write的許可權才可以寫    if(characteristic.properties & CBCharacteristicPropertyWrite){        /*            最好一個type參數可以為CBCharacteristicWriteWithResponse或type:CBCharacteristicWriteWithResponse,區別是是否會有反饋        */        [peripheral writeValue:value forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];    }else{        NSLog(@"該欄位不可寫。");    }}

8、訂閱Characteristic的通知
一般在discoverCharacteristic的代理中,發現了類型是notify的characteristic,直接就可以訂閱了

    //設定通知-(void)notifyCharacteristic:(CBPeripheral *)peripheral            characteristic:(CBCharacteristic *)characteristic{    //設定通知,資料通知會進入:didUpdateValueForCharacteristic方法    [peripheral setNotifyValue:YES forCharacteristic:characteristic];}//取消通知-(void)cancelNotifyCharacteristic:(CBPeripheral *)peripheral             characteristic:(CBCharacteristic *)characteristic{     [peripheral setNotifyValue:NO forCharacteristic:characteristic];}

9、中斷連線(disconnect)

    //停止掃描並中斷連線-(void)disconnectPeripheral:(CBCentralManager *)centralManager                 peripheral:(CBPeripheral *)peripheral{    //停止掃描    [centralManager stopScan];    //中斷連線    [centralManager cancelPeripheralConnection:peripheral];}
iOS中藍芽模組OTA升級(YModem協議)

見下一篇文章

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.