iOS藍(lán)牙開(kāi)發(fā)

iOS藍(lán)牙開(kāi)發(fā)(一)藍(lán)牙相關(guān)基礎(chǔ)知識(shí)

藍(lán)牙常見(jiàn)名稱(chēng)和縮寫(xiě)

  • MFI ======= make for ipad ,iphone, itouch 專(zhuān)們?yōu)樘O(píng)果設(shè)備制作的設(shè)備

  • BLE ==== buletouch low energy,藍(lán)牙4.0設(shè)備因?yàn)榈秃碾?,所以也叫做BLE

  • peripheral,central == 外設(shè)和中心,發(fā)起連接的時(shí)central,被連接的設(shè)備為perilheral

  • service and characteristic === 服務(wù)和特征 每個(gè)設(shè)備會(huì)提供服務(wù)和特征,類(lèi)似于服務(wù)端的api,但是機(jī)構(gòu)不同。每個(gè)外設(shè)會(huì)有很多服務(wù),每個(gè)服務(wù)中包含很多字段,這些字段的權(quán)限一般分為 讀read,寫(xiě)write,通知notiy幾種,就是我們連接設(shè)備后具體需要操作的內(nèi)容。

  • Description 每個(gè)characteristic可以對(duì)應(yīng)一個(gè)或多個(gè)Description用戶(hù)描述characteristic的信息或?qū)傩?/p>

  • MFI === 開(kāi)發(fā)使用ExternalAccessory 框架

  • 4.0 BLE === 開(kāi)發(fā)使用CoreBluetooth 框架

藍(lán)牙基礎(chǔ)知識(shí)

CoreBluetooth框架的核心其實(shí)是兩個(gè)東西,peripheral和central, 可以理解成外設(shè)和中心。對(duì)應(yīng)他們分別有一組相關(guān)的API和類(lèi)

image
  • 這兩組api分別對(duì)應(yīng)不同的業(yè)務(wù)場(chǎng)景,左側(cè)叫做中心模式,就是以你的app作為中心,連接其他的外設(shè)的場(chǎng)景,而右側(cè)稱(chēng)為外設(shè)模式,使用手機(jī)作為外設(shè)別其他中心設(shè)備操作的場(chǎng)景。

  • 服務(wù)和特征,特征的屬性(service and characteristic):
    每個(gè)設(shè)備都會(huì)有一些服務(wù),每個(gè)服務(wù)里面都會(huì)有一些特征,特征就是具體鍵值對(duì),提供數(shù)據(jù)的地方。每個(gè)特征屬性分為這么幾種:讀,寫(xiě),通知這么幾種方式。

      //objcetive c特征的定義枚舉
      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
      };
    
    

外設(shè)、服務(wù)、特征間的關(guān)系

image

藍(lán)牙中心模式流程

1\. 建立中心角色
2\. 掃描外設(shè)(discover)
3\. 連接外設(shè)(connect)
4\. 掃描外設(shè)中的服務(wù)和特征(discover)
    - 4.1 獲取外設(shè)的services
    - 4.2 獲取外設(shè)的Characteristics,獲取Characteristics的值,獲取Characteristics的Descriptor和Descriptor的值
5\. 與外設(shè)做數(shù)據(jù)交互(explore and interact)
6\. 訂閱Characteristic的通知
7\. 斷開(kāi)連接(disconnect)

藍(lán)牙外設(shè)模式流程

1\. 啟動(dòng)一個(gè)Peripheral管理對(duì)象
2\. 本地Peripheral設(shè)置服務(wù),特性,描述,權(quán)限等等
3\. Peripheral發(fā)送廣告
4\. 設(shè)置處理訂閱、取消訂閱、讀characteristic、寫(xiě)characteristic的委托方法

藍(lán)牙設(shè)備狀態(tài)

1\. 待機(jī)狀態(tài)(standby):設(shè)備沒(méi)有傳輸和發(fā)送數(shù)據(jù),并且沒(méi)有連接到任何設(shè)
2\. 廣播狀態(tài)(Advertiser):周期性廣播狀態(tài)
3\. 掃描狀態(tài)(Scanner):主動(dòng)尋找正在廣播的設(shè)備
4\. 發(fā)起鏈接狀態(tài)(Initiator):主動(dòng)向掃描設(shè)備發(fā)起連接。
5\. 主設(shè)備(Master):作為主設(shè)備連接到其他設(shè)備。
6\. 從設(shè)備(Slave):作為從設(shè)備連接到其他設(shè)備。

藍(lán)牙設(shè)備的五種工作狀態(tài)

  • 準(zhǔn)備(standby)
  • 廣播(advertising)
  • 監(jiān)聽(tīng)掃描(Scanning
  • 發(fā)起連接(Initiating)
  • 已連接(Connected)

藍(lán)牙和版本的使用限制

  • 藍(lán)牙2.0 === 越獄設(shè)備
  • 藍(lán)牙4.0 === IOS6 以上
  • MFI認(rèn)證設(shè)備(Make For ipod/ipad/iphone) === 無(wú)限制

名詞解釋

  • GAAT : Generic Attribute Profile , GATT配置文件是一個(gè)通用規(guī)范,用于在BLE鏈路上發(fā)送和接收被稱(chēng)為“屬性”的數(shù)據(jù)塊。目前所有的BLE應(yīng)用都基于GATT。 藍(lán)牙SIG規(guī)定了許多低功耗設(shè)備的配置文件。配置文件是設(shè)備如何在特定的應(yīng)用程序中工作的規(guī)格說(shuō)明。注意一個(gè)設(shè)備可以實(shí)現(xiàn)多個(gè)配置文件。例如,一個(gè)設(shè)備可能包括心率監(jiān)測(cè)儀和電量檢測(cè)。
  • Characteristic 一個(gè)characteristic包括一個(gè)單一變量和0-n個(gè)用來(lái)描述characteristic變量的descriptor,characteristic可以被認(rèn)為是一個(gè)類(lèi)型,類(lèi) 似于類(lèi)。
  • Descriptor Descriptor用來(lái)描述characteristic變量的屬性。例如,一個(gè)descriptor可以規(guī)定一個(gè)可讀的描述,或者一個(gè)characteristic變量可接受的范圍,或者一個(gè)characteristic變量特定的測(cè)量單位。 Service service是characteristic的集合。例如,你可能有一個(gè)叫“Heart Rate Monitor(心率監(jiān)測(cè)儀)”的service,它包括了很多characteristics,如“heart rate measurement(心率測(cè)量)”等。你可以在bluetooth.org 找到一個(gè)目前支持的基于GATT的配置文件和服務(wù)列表。

ios連接外設(shè)的代碼實(shí)現(xiàn)流程

  1. 建立中心角色
  2. 掃描外設(shè)(discover)
  3. 連接外設(shè)(connect)
  4. 掃描外設(shè)中的服務(wù)和特征(discover)
    • 4.1 獲取外設(shè)的services
    • 4.2 獲取外設(shè)的Characteristics,獲取Characteristics的值,獲取Characteristics的Descriptor和Descriptor的值
  5. 與外設(shè)做數(shù)據(jù)交互(explore and interact)
  6. 訂閱Characteristic的通知
  7. 斷開(kāi)連接(disconnect)
    準(zhǔn)備環(huán)境

1 xcode
2 開(kāi)發(fā)證書(shū)和手機(jī)(藍(lán)牙程序需要使用使用真機(jī)調(diào)試,使用模擬器也可以調(diào)試,但是方法很蛋疼,我會(huì)放在最后說(shuō))
3 藍(lán)牙外設(shè)
實(shí)現(xiàn)步驟

1 導(dǎo)入CoreBluetooth頭文件,建立主設(shè)備管理類(lèi),設(shè)置主設(shè)備委托

#import <CoreBluetooth/CoreBluetooth.h>
@interface ViewController : UIViewController<CBCentralManagerDelegate>


@interface ViewController (){
    //系統(tǒng)藍(lán)牙設(shè)備管理對(duì)象,可以把他理解為主設(shè)備,通過(guò)他,可以去掃描和鏈接外設(shè)
    CBCentralManager *manager;
    //用于保存被發(fā)現(xiàn)設(shè)備
    NSMutableArray *peripherals;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    /*
     設(shè)置主設(shè)備的委托,CBCentralManagerDelegate
        必須實(shí)現(xiàn)的:
        - (void)centralManagerDidUpdateState:(CBCentralManager *)central;//主設(shè)備狀態(tài)改變的委托,在初始化CBCentralManager的適合會(huì)打開(kāi)設(shè)備,只有當(dāng)設(shè)備正確打開(kāi)后才能使用
        其他選擇實(shí)現(xiàn)的委托中比較重要的:
        - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI; //找到外設(shè)的委托
        - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral;//連接外設(shè)成功的委托
        - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;//外設(shè)連接失敗的委托
        - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;//斷開(kāi)外設(shè)的委托
    */
     //初始化并設(shè)置委托和線程隊(duì)列,最好一個(gè)線程的參數(shù)可以為nil,默認(rèn)會(huì)就main線程
     manager = [[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_main_queue()];

2 掃描外設(shè)(discover),掃描外設(shè)的方法我們放在centralManager成功打開(kāi)的委托中,因?yàn)橹挥性O(shè)備成功打開(kāi),才能開(kāi)始掃描,否則會(huì)報(bào)錯(cuò)。

    -(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");
                //開(kāi)始掃描周?chē)耐庠O(shè)
                /*
                 第一個(gè)參數(shù)nil就是掃描周?chē)械耐庠O(shè),掃描到外設(shè)后會(huì)進(jìn)入
                      - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI;
                 */
                [manager scanForPeripheralsWithServices:nil options:nil];

                break;
            default:
                break;
        }

    }

    //掃描到設(shè)備會(huì)進(jìn)入方法
    -(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{

        NSLog(@"當(dāng)掃描到設(shè)備:%@",peripheral.name);
        //接下來(lái)可以連接設(shè)備

    }

3 連接外設(shè)(connect)

    //掃描到設(shè)備會(huì)進(jìn)入方法
    -(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{

        //接下連接我們的測(cè)試設(shè)備,如果你沒(méi)有設(shè)備,可以下載一個(gè)app叫l(wèi)ightbule的app去模擬一個(gè)設(shè)備
        //這里自己去設(shè)置下連接規(guī)則,我設(shè)置的是P開(kāi)頭的設(shè)備
               if ([peripheral.name hasPrefix:@"P"]){
               /*
                   一個(gè)主設(shè)備最多能連7個(gè)外設(shè),每個(gè)外設(shè)最多只能給一個(gè)主設(shè)備連接,連接成功,失敗,斷開(kāi)會(huì)進(jìn)入各自的委托
                - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral;//連接外設(shè)成功的委托
                - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;//外設(shè)連接失敗的委托
                - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;//斷開(kāi)外設(shè)的委托
                */

                //找到的設(shè)備必須持有它,否則CBCentralManager中也不會(huì)保存peripheral,那么CBPeripheralDelegate中的方法也不會(huì)被調(diào)用?。?                [peripherals addObject:peripheral];
                //連接設(shè)備
               [manager connectPeripheral:peripheral options:nil];
           }

    }


    //連接到Peripherals-成功
    - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
    {
        NSLog(@">>>連接到名稱(chēng)為(%@)的設(shè)備-成功",peripheral.name);
    }

    //連接到Peripherals-失敗
    -(void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
    {
        NSLog(@">>>連接到名稱(chēng)為(%@)的設(shè)備-失敗,原因:%@",[peripheral name],[error localizedDescription]);
    }

    //Peripherals斷開(kāi)連接
    - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
        NSLog(@">>>外設(shè)連接斷開(kāi)連接 %@: %@\n", [peripheral name], [error localizedDescription]);

    }

有一點(diǎn)非常容易出錯(cuò),大家請(qǐng)注意。在 didDiscoverPeripheral這個(gè)委托中有這一行

//找到的設(shè)備必須持有它,否則CBCentralManager中也不會(huì)保存peripheral,那么CBPeripheralDelegate中的方法也不會(huì)被調(diào)用?。?br> [peripherals addObject:peripheral];
請(qǐng)?zhí)貏e注意,如果不保存,會(huì)影響到后面的方法執(zhí)行,這個(gè)地方很多人出錯(cuò),在我的藍(lán)牙交流群中每天幾乎都會(huì)因?yàn)檫@個(gè)問(wèn)題導(dǎo)致無(wú)法連接和對(duì)外設(shè)后續(xù)的操作。

大家也可以看一下這個(gè)委托在xcode中的說(shuō)明,重點(diǎn)看@discussion中的內(nèi)容,里面特別指出了需要retained對(duì)象。

/*!

  • @method centralManager:didDiscoverPeripheral:advertisementData:RSSI:
  • @param central The central manager providing this update.
  • @param peripheral A <code>CBPeripheral</code> object.
  • @param advertisementData A dictionary containing any advertisement and scan response data.
  • @param RSSI The current RSSI of <i>peripheral</i>, in dBm. A value of <code>127</code> is reserved and indicates the RSSI
  •                          was not available.
    
  • @discussion This method is invoked while scanning, upon the discovery of <i>peripheral</i> by <i>central</i>. A discovered peripheral must
  •                          be retained in order to use it; otherwise, it is assumed to not be of interest and will be cleaned up by the central manager. For
    
  •                          a list of <i>advertisementData</i> keys, see {@link CBAdvertisementDataLocalNameKey} and other similar constants.
    
  • @seealso CBAdvertisementData.h

*/

  • (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *, id> *)advertisementData RSSI:(NSNumber *)RSSI;
    4掃描外設(shè)中的服務(wù)和特征(discover)

設(shè)備連接成功后,就可以掃描設(shè)備的服務(wù)了,同樣是通過(guò)委托形式,掃描到結(jié)果后會(huì)進(jìn)入委托方法。但是這個(gè)委托已經(jīng)不再是主設(shè)備的委托(CBCentralManagerDelegate),而是外設(shè)的委托(CBPeripheralDelegate),這個(gè)委托包含了主設(shè)備與外設(shè)交互的許多 回叫方法,包括獲取services,獲取characteristics,獲取characteristics的值,獲取characteristics的Descriptor,和Descriptor的值,寫(xiě)數(shù)據(jù),讀rssi,用通知的方式訂閱數(shù)據(jù)等等。

4.1獲取外設(shè)的services

    //連接到Peripherals-成功
    - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
    {
        NSLog(@">>>連接到名稱(chēng)為(%@)的設(shè)備-成功",peripheral.name);
        //設(shè)置的peripheral委托CBPeripheralDelegate
        //@interface ViewController : UIViewController<CBCentralManagerDelegate,CBPeripheralDelegate>
        [peripheral setDelegate:self];
        //掃描外設(shè)Services,成功后會(huì)進(jìn)入方法:-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
        [peripheral discoverServices:nil];

    }

    //掃描到Services
    -(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
        //  NSLog(@">>>掃描到服務(wù):%@",peripheral.services);
        if (error)
        {
            NSLog(@">>>Discovered services for %@ with error: %@", peripheral.name, [error localizedDescription]);
            return;
        }

        for (CBService *service in peripheral.services) {
                         NSLog(@"%@",service.UUID);
                         //掃描每個(gè)service的Characteristics,掃描到后會(huì)進(jìn)入方法: -(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
                         [peripheral discoverCharacteristics:nil forService:service];
                     }

    }

4.2獲取外設(shè)的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的值,讀到數(shù)據(jù)會(huì)進(jìn)入方法:-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
     for (CBCharacteristic *characteristic in service.characteristics){
         {
             [peripheral readValueForCharacteristic:characteristic];
         }
     }

     //搜索Characteristic的Descriptors,讀到數(shù)據(jù)會(huì)進(jìn)入方法:-(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的類(lèi)型是NSData,具體開(kāi)發(fā)時(shí),會(huì)根據(jù)外設(shè)協(xié)議制定的方式去解析數(shù)據(jù)
    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
    //這個(gè)descriptor都是對(duì)于characteristic的描述,一般都是字符串,所以這里我們轉(zhuǎn)換成字符串去解析
    NSLog(@"characteristic uuid:%@  value:%@",[NSString stringWithFormat:@"%@",descriptor.UUID],descriptor.value);
}

5 把數(shù)據(jù)寫(xiě)到Characteristic中

//寫(xiě)數(shù)據(jù)
-(void)writeCharacteristic:(CBPeripheral *)peripheral
            characteristic:(CBCharacteristic *)characteristic
                     value:(NSData *)value{

    //打印出 characteristic 的權(quán)限,可以看到有很多種,這是一個(gè)NS_OPTIONS,就是可以同時(shí)用于好幾個(gè)值,常見(jiàn)的有read,write,notify,indicate,知知道這幾個(gè)基本就夠用了,前連個(gè)是讀寫(xiě)權(quán)限,后兩個(gè)都是通知,兩種不同的通知方式。
    /*
     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的權(quán)限才可以寫(xiě)
    if(characteristic.properties & CBCharacteristicPropertyWrite){
        /*
            最好一個(gè)type參數(shù)可以為CBCharacteristicWriteWithResponse或type:CBCharacteristicWriteWithResponse,區(qū)別是是否會(huì)有反饋
        */
        [peripheral writeValue:value forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
    }else{
        NSLog(@"該字段不可寫(xiě)!");
    }


}

6 訂閱Characteristic的通知

//設(shè)置通知
-(void)notifyCharacteristic:(CBPeripheral *)peripheral
            characteristic:(CBCharacteristic *)characteristic{
    //設(shè)置通知,數(shù)據(jù)通知會(huì)進(jìn)入:didUpdateValueForCharacteristic方法
    [peripheral setNotifyValue:YES forCharacteristic:characteristic];

}

//取消通知
-(void)cancelNotifyCharacteristic:(CBPeripheral *)peripheral
             characteristic:(CBCharacteristic *)characteristic{

     [peripheral setNotifyValue:NO forCharacteristic:characteristic];
}

7 斷開(kāi)連接(disconnect)

//停止掃描并斷開(kāi)連接
-(void)disconnectPeripheral:(CBCentralManager *)centralManager
                 peripheral:(CBPeripheral *)peripheral{
    //停止掃描
    [centralManager stopScan];
    //斷開(kāi)連接
    [centralManager cancelPeripheralConnection:peripheral];
}

本文轉(zhuǎn)載自

劉彥瑋的技術(shù)博客

最后推薦一個(gè)框架# BabyBluetooth

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容