iOS基礎(chǔ)之藍(lán)牙

目錄
    1. 藍(lán)牙
       1.1 中央設(shè)備(接收數(shù)據(jù))常用
       1.2 外圍設(shè)備(發(fā)送數(shù)據(jù))很少使用(測(cè)試協(xié)議時(shí)使用)
       1.3 相關(guān)類(lèi)
    2. WiFi

1. 藍(lán)牙

概念

CoreBluetooth藍(lán)牙

    藍(lán)牙開(kāi)發(fā)分為2種:
        1.手機(jī)作為中央設(shè)備(常用)連接藍(lán)牙設(shè)備赛惩;
        2.手機(jī)作為外圍設(shè)備(不常用)連接中央設(shè)備尼荆。

    藍(lán)牙4.0(現(xiàn)在多數(shù)設(shè)備已支持)以低功耗著稱(chēng)奕剃,又稱(chēng)BLE(Bluetoothlow energy)镰矿。
    藍(lán)牙的數(shù)據(jù)交互類(lèi)似于接口蛹尝,硬件service的UUID(相當(dāng)于主地址)加上characteristic的UUID(相當(dāng)于后邊路徑)岖常。
    所有可用的iOS設(shè)備既可以作為周邊(Peripheral)也可以作為中央(Central)歧寺,但不可以同時(shí)既是周邊也是中央翅雏。
    藍(lán)牙只能支持16進(jìn)制,且每次傳輸最多20字節(jié)梳码。
    藍(lán)牙開(kāi)發(fā)最核心的不是代碼(代碼是固定的)隐圾,而是協(xié)議(一般藍(lán)牙的數(shù)據(jù)協(xié)議都會(huì)加密,不加密則任何人都可以連接硬件)
    藍(lán)牙設(shè)備向 中心設(shè)備 發(fā)送廣播掰茶,必定有一個(gè)或多個(gè)服務(wù)暇藏,服務(wù)包含一個(gè)或多個(gè)特征(是和外界交互的最小單位)。


歷史框架
    <GameKit.framework>             只能用于iOS設(shè)備之間的連接(ios7前)
    <MultipeerConnectivity.framework>   只能用于iOS設(shè)備之間的連接(ios7后)
    <ExternalAccessory.framework>       可用于第三方藍(lán)牙設(shè)備交互濒蒋,但是藍(lán)牙設(shè)備必須經(jīng)過(guò)蘋(píng)果MFi認(rèn)證
    <CoreBluetooth.framework>           目前世界上最流行的藍(lán)牙框架(99%)
相關(guān)名詞
    Central(中心設(shè)備)接收并處理周邊設(shè)備發(fā)送的數(shù)據(jù)
    Peripheral(周邊設(shè)備)不斷發(fā)送數(shù)據(jù)
    advertising(廣播)
    Services(服務(wù))
    Characteristic(特征)
使用步驟
    1.創(chuàng)建Central Manager中心設(shè)備管理者
    2.搜索外圍設(shè)備
    3.連接外圍設(shè)備
    4.尋找外圍設(shè)備的某服務(wù)中的某特征
    5.從外圍設(shè)備讀取數(shù)據(jù)/向外圍設(shè)備發(fā)送數(shù)據(jù)  
    6.斷開(kāi)連接

注意:
  info.plist + 權(quán)限
      Privacy - Bluetooth Peripheral Usage Description   App需要訪(fǎng)問(wèn)藍(lán)牙

1.1 中央設(shè)備(接收數(shù)據(jù))常用

import "YTCentralViewController.h"
#import <CoreBluetooth/CoreBluetooth.h>

#define ServiceUUID [CBUUID UUIDWithString:@"0000fee7-0000-1000-8000-00805f9b34fb"]
#define WirteCharactUUID [CBUUID UUIDWithString:@"000036f5-0000-1000-8000-00805f9b34fb"]
#define ReadCharactUUID [CBUUID UUIDWithString:@"000036f6-0000-1000-8000-00805f9b34fb"]

@interface YTCentralViewController ()<CBCentralManagerDelegate,CBPeripheralDelegate>
@property (nonatomic,strong) CBCentralManager *centralManager;      // 創(chuàng)建中心設(shè)備管理者(數(shù)據(jù)接收方)
@property (nonatomic,strong) NSMutableArray *peripheralArr;         // 存放外圍設(shè)備
@end

@implementation YTCentralViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 1.創(chuàng)建中心設(shè)備管理者
    self.centralManager=[[CBCentralManager alloc]initWithDelegate:self queue:nil];
}
-(void)dealloc{
    self.centralManager=nil;
}


#pragma mark dele CBCentralManagerDelegate
// 2.藍(lán)牙狀態(tài)發(fā)生改變時(shí)調(diào)用(必須實(shí)現(xiàn))盐碱,創(chuàng)建中心設(shè)備管理者調(diào)用一次
-(void)centralManagerDidUpdateState:(CBCentralManager *)central{
    if (@available(iOS 10.0, *)) {
    switch (central.state) {
        case CBManagerStatePoweredOn:{  // 藍(lán)牙已打開(kāi)
            NSLog(@"藍(lán)牙開(kāi)啟");
            
            // 2.1 掃描外圍設(shè)備(nil:掃描所有service)
            [self.centralManager scanForPeripheralsWithServices:nil options:nil];
        }
            break;
        case CBManagerStatePoweredOff:{ // 藍(lán)牙未打開(kāi)
            NSLog(@"藍(lán)牙關(guān)閉");
        }
            break;
        case CBManagerStateUnauthorized:{
            NSLog(@"未授權(quán)使用藍(lán)牙");
        }
            break;
        case CBManagerStateUnsupported:{
            NSLog(@"不支持藍(lán)牙");
        }
            break;
        case CBManagerStateResetting:{
            NSLog(@"");
        }
            break;
        case CBManagerStateUnknown:{
            NSLog(@"");
        }
            break;
        default:{
            NSLog(@"");
        }
        break;
    }
    }
}
// 3.掃描到外圍設(shè)備后調(diào)用
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI{
    
    // 3.1 找的唯一對(duì)應(yīng)的設(shè)備后停止掃描
    if([peripheral.name isEqualToString:@"device01"]||[peripheral.name isEqualToString:@"iPhone"]){
        // 停止掃描
        [self.centralManager stopScan];
    }else{
        return;
    }
    
    // 添加掃描設(shè)備到數(shù)組,并聯(lián)入外圍設(shè)備
    if(peripheral){
        //
        if(![self.peripheralArr containsObject:peripheral]){
            [self.peripheralArr addObject:peripheral];
        }
        // 3.2 聯(lián)入外圍設(shè)備(聯(lián)接成功后調(diào)用didConnectPeripheral)
        [self.centralManager connectPeripheral:peripheral options:nil];
    }
}
// 4.聯(lián)入外圍設(shè)備后調(diào)用
-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{

    // 設(shè)置外圍設(shè)備的dele  CBPeripheralDelegate
    [peripheral setDelegate:self];
    // 外圍設(shè)備尋找服務(wù)
    [peripheral discoverServices:@[ServiceUUID]];
}
// 4.1聯(lián)入外圍設(shè)備失敗后調(diào)用
-(void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
    //
    NSLog(@"error connect");
}
/*
// 取消聯(lián)接后調(diào)用
-(void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{}
// 進(jìn)入后臺(tái)前調(diào)用保存信息沪伙?
-(void)centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary<NSString *,id> *)dict{}
  */
    
    
    
    
#pragma mark dele CBPeripheralDelegate
// 5.外圍設(shè)備尋找到服務(wù)后調(diào)用
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
    if(error){  // 尋找服務(wù)失敗
        NSLog(@"尋找服務(wù)失敗");
    }
    
    // 從外圍設(shè)備的服務(wù)中找到對(duì)應(yīng)service和對(duì)應(yīng)charact
    for(CBService *service in peripheral.services){
        if([service.UUID isEqual:ServiceUUID]){
            // 尋找對(duì)應(yīng)特征
            [peripheral discoverCharacteristics:nil forService:service];
        }
    }
}

// 6.尋找到特征時(shí)調(diào)用
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
    if(error){     // 尋找特征出錯(cuò)
        NSLog(@"尋找特征時(shí)出錯(cuò)");
    }
    // 找到對(duì)應(yīng)service服務(wù)對(duì)應(yīng)的charact特征瓮顽,
    if([service.UUID isEqual:ServiceUUID]){
        for(CBCharacteristic *charact in service.characteristics){
            if([charact.UUID isEqual:WirteCharactUUID]){    // 寫(xiě)
                
                //
                Byte reg[16];
                reg[0]=0x05;
                reg[1]=0x01;
                reg[2]=0x06;
                
                for(int i=0;i<13;i++){
                    reg[i+3]=0x01;
                }
                
                NSData *data=[NSData dataWithBytes:reg length:16];
                [peripheral writeValue:data forCharacteristic:charact type:CBCharacteristicWriteWithResponse];
                
                /*
                // 更新通知狀態(tài):(調(diào)用didUpdateNoti,外圍設(shè)備會(huì)收到訂閱通知并添加到數(shù)據(jù)源中--需要發(fā)送數(shù)據(jù)時(shí)發(fā)送)
                [peripheral setNotifyValue:true forCharacteristic:charact];
                
                 // 或
                 // 讀取特征值
                 [peripheral readValueForCharacteristic:charact];
                 if(charact.value){
                 NSLog(@"特征值:%@",[[NSString alloc]initWithData:charact.value encoding:NSUTF8StringEncoding]);
                 }
                 */
            }else if([charact.UUID isEqual:ReadCharactUUID]){   // 讀
                // 1:監(jiān)聽(tīng)通知(收到通知時(shí)調(diào)用didUpdateNoti围橡,在其中調(diào)用2)(用于持續(xù)讀扰臁)
                [peripheral setNotifyValue:true forCharacteristic:charact];
                
                // 或
                
                // 2:調(diào)用didUpdateValueForC從外圍設(shè)備中讀取數(shù)據(jù)(用于一次讀取)
                [peripheral readValueForCharacteristic:charact];
            }
        }
    }
}
// 7.通知狀態(tài)更新時(shí)調(diào)用
-(void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
    if(error){      // 通知狀態(tài)更新時(shí)出錯(cuò)
        NSLog(@"通知狀態(tài)更新時(shí)出錯(cuò)");
        return;
    }
    //
    if([characteristic.UUID isEqual:WirteCharactUUID]){

    }else if([characteristic.UUID isEqual:ReadCharactUUID]){
        
        if(characteristic.isNotifying){ // 正在監(jiān)聽(tīng)(通知狀態(tài)為true)
            if(characteristic.properties==CBCharacteristicPropertyNotify){  // 調(diào)用setNotifyValue后進(jìn)入
                NSLog(@"已訂閱特征通知翁授。 ");
                return;
            }else if(characteristic.properties==CBCharacteristicPropertyRead){  // 外圍設(shè)備發(fā)送數(shù)據(jù)后進(jìn)入
                // 調(diào)用didUpdateValueForC從外圍設(shè)備中讀取數(shù)據(jù)
                [peripheral readValueForCharacteristic:characteristic];
            }
        }else{  // 停止監(jiān)聽(tīng)(通知狀態(tài)為false)
            NSLog(@"stop 監(jiān)聽(tīng)通知");
            // 取消連接
            [_centralManager cancelPeripheralConnection:peripheral];
        }
    }
}

// 8. 從外圍設(shè)備讀取數(shù)據(jù)(readValueForCharacteristic時(shí)會(huì)調(diào)用)
-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
    if(error){
        NSLog(@"讀取數(shù)據(jù)出錯(cuò)");
        return;
    }
    if(characteristic.value){
        NSString *value=[[NSString alloc]initWithData:characteristic.value encoding:NSUTF8StringEncoding];
        NSLog(@"讀取到數(shù)據(jù):%@",value);
    }else{          // 無(wú)數(shù)據(jù)
        NSLog(@"未發(fā)現(xiàn)特征值");
    }
}





-(NSMutableArray *)peripheralArr{
    if(!_peripheralArr){
        _peripheralArr=[NSMutableArray arrayWithCapacity:10];
    }
    return _peripheralArr;
}

@end

1.2 外圍設(shè)備(發(fā)送數(shù)據(jù))

很少使用

    可用來(lái)在設(shè)備未做好之前測(cè)試協(xié)議拣播。
#import "YTPeripheralViewController.h"
#import <CoreBluetooth/CoreBluetooth.h>

#define ServiceUUID [CBUUID UUIDWithString:@"0000fee7-0000-1000-8000-00805f9b34fb"]
#define WriteCharactUUID [CBUUID UUIDWithString:@"000036f5-0000-1000-8000-00805f9b34fb"]
#define ReadCharactUUID [CBUUID UUIDWithString:@"000036f6-0000-1000-8000-00805f9b34fb"]


@interface YTPeripheralViewController ()<CBPeripheralManagerDelegate>
@property (nonatomic,strong) CBPeripheralManager *peripheralManager;    // 發(fā)射數(shù)據(jù)管理者(外圍設(shè)備)
@property (nonatomic,strong) NSMutableArray *centralArr;                // 聯(lián)入的設(shè)備
@end

@implementation YTPeripheralViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 1.創(chuàng)建 外圍設(shè)備管理者(發(fā)射數(shù)據(jù))
    self.peripheralManager=[[CBPeripheralManager alloc]initWithDelegate:self queue:nil];
}
-(void)dealloc{
    self.peripheralManager=nil;
}


#pragma mark dele
// 2.藍(lán)牙狀態(tài)發(fā)生改變時(shí)調(diào)用(必須實(shí)現(xiàn))
-(void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral{
    //
    switch (peripheral.state) {
        case CBManagerStatePoweredOn:{  // 藍(lán)牙已打開(kāi)
            NSLog(@"BLE open");
            
            // 2.1 添加服務(wù)
            CBMutableService *serviceM=[[CBMutableService alloc]initWithType:ServiceUUID primary:true];
            // 給服務(wù)添加特征
            CBMutableCharacteristic *writeCharaM=[[CBMutableCharacteristic alloc]initWithType:WriteCharactUUID properties:CBCharacteristicPropertyWrite value:nil permissions:CBAttributePermissionsWriteable|CBCharacteristicPropertyNotify];
            CBMutableCharacteristic *readCharaM=[[CBMutableCharacteristic alloc]initWithType:ReadCharactUUID properties:CBCharacteristicPropertyRead value:nil permissions:CBAttributePermissionsReadable|CBCharacteristicPropertyNotify];
            /*
             CBCharacteristicPropertyBroadcast                                                = 0x01,
             CBCharacteristicPropertyRead                                                     = 0x02,
             CBCharacteristicPropertyWriteWithoutResponse                                     = 0x04,
             CBCharacteristicPropertyWrite                                                    = 0x08,
             CBCharacteristicPropertyNotify                                                   = 0x10,
             CBCharacteristicPropertyIndicate                                                 = 0x20,
             CBCharacteristicPropertyAuthenticatedSignedWrites                                = 0x40,
             CBCharacteristicPropertyExtendedProperties                                       = 0x80,
             CBCharacteristicPropertyNotifyEncryptionRequired NS_ENUM_AVAILABLE(10_9, 6_0)    = 0x100,
             CBCharacteristicPropertyIndicateEncryptionRequired NS_ENUM_AVAILABLE(10_9, 6_0)  = 0x200
             */
            /*
             CBAttributePermissionsReadable                   = 0x01,
             CBAttributePermissionsWriteable                  = 0x02,
             CBAttributePermissionsReadEncryptionRequired     = 0x04,
             CBAttributePermissionsWriteEncryptionRequired    = 0x08
             */
            [serviceM setCharacteristics:@[writeCharaM,readCharaM]];
            // 會(huì)調(diào)用didAddService方法
            [self.peripheralManager addService:serviceM];
        }
            break;
        case CBManagerStatePoweredOff:{  // 藍(lán)牙未打開(kāi)
            //
            NSLog(@"未打開(kāi)藍(lán)牙BLE");
        }
            break;
        default:{
        }
            break;
    }
}
// 3.外圍設(shè)備添加servie后調(diào)用
-(void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error{
    if(error){      // 添加servie出錯(cuò)
        NSLog(@"錯(cuò)誤:%@",error.localizedDescription);
        return;
    }
    
    // 啟動(dòng)廣播
    // 調(diào)用DidStartAdvertising
    [self.peripheralManager startAdvertising:@{CBAdvertisementDataLocalNameKey:@"外圍設(shè)備名"}];
}
// 3.1啟動(dòng)廣播
-(void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(NSError *)error{
    if(error){      // 啟動(dòng)廣播出錯(cuò)
        NSLog(@"start error");
        return;
    }
    NSLog(@"開(kāi)始 廣播");
}
// 4.有設(shè)備聯(lián)入后調(diào)用
-(void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic{
    // 添加中心設(shè)備到數(shù)組
    if(![self.centralArr containsObject:central]){
        [self.centralArr addObject:central];
    }
}
// 4.1有設(shè)備取消聯(lián)入后調(diào)用
-(void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic{
    NSLog(@"cancel");
}
// 5.收到寫(xiě)數(shù)據(jù)請(qǐng)求后調(diào)用
-(void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray<CBATTRequest *> *)requests{
    CBATTRequest *request = requests.lastObject;
    NSString *content = [[NSString alloc] initWithData:request.value encoding:NSUTF8StringEncoding];
}
// 5.1 收到讀數(shù)據(jù)請(qǐng)求后調(diào)用
-(void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request{
    //
    Byte reg[16];
    reg[0]=0x05;
    reg[1]=0x02;
    reg[2]=0x01;
    reg[3]=0x00;
    for(int i=0;i<12;i++){
        reg[i+4]=0x00;
    }
    NSData *data=[NSData dataWithBytes:reg length:16];
    request.value = data;
    //    [@"hello" dataUsingEncoding:NSUTF8StringEncoding];
    [peripheral respondToRequest:request withResult:CBATTErrorSuccess];
}
// 6.進(jìn)入后臺(tái)存儲(chǔ)數(shù)據(jù)?
-(void)peripheralManager:(CBPeripheralManager *)peripheral willRestoreState:(NSDictionary<NSString *,id> *)dict{
    //
    NSLog(@"will restore state");
}
// 7.updateValue:forCharacteristic:onSubscribedCentrals失敗后再次準(zhǔn)備好更新特征值時(shí)調(diào)用
-(void)peripheralManagerIsReadyToUpdateSubscribers:(CBPeripheralManager *)peripheral{}

// 懶加載(已聯(lián)入的中心設(shè)備)
-(NSMutableArray *)centralArr{
    if(!_centralArr){
        _centralArr=[NSMutableArray arrayWithCapacity:10];
    }
    return _centralArr;
}
@end

1.3 相關(guān)類(lèi)

    // CBCentralManager 中心設(shè)備管理者(用來(lái)管理中心設(shè)備:掃描/連接 外圍設(shè)備)
    // 創(chuàng)建        CBCentralManagerDelegate
    // CBCentralManager *centralManager=[[CBCentralManager alloc]initWithDelegate:self queue:nil];
    CBCentralManager *centralManager=[[CBCentralManager alloc]initWithDelegate:self queue:nil options:@{}];
    /*
     CBCentralManagerOptionShowPowerAlertKey            @(BOOL) 若藍(lán)牙未打開(kāi)收擦,是否彈出alert
     CBCentralManagerOptionRestoreIdentifierKey         @""     用于藍(lán)牙恢復(fù)鏈接
    */
    // CBCentralManager *centralManager=[CBCentralManager new];
    // [centralManager setDelegate:self];
    // 獲取已連接的外圍藍(lán)牙設(shè)備(根據(jù)serviceID)
    NSArray<CBPeripheral *> *perArr=[centralManager retrieveConnectedPeripheralsWithServices:@[[CBUUID UUIDWithString:@"NSUUID"]]];
    // 獲取已連接的外圍藍(lán)牙設(shè)備(根據(jù)Identifier)
    NSArray<CBPeripheral *> *perArr=[centralManager retrievePeripheralsWithIdentifiers:@[[CBUUID UUIDWithString:@"SERVICE ID"]]];
    // 掃描外圍設(shè)備(services寫(xiě)nil 表示掃描所有)
    [centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:@"SERVICE ID"]] options:@{}];
    /*
     CBCentralManagerScanOptionAllowDuplicatesKey       @(BOOL) 是否重復(fù)掃描已發(fā)現(xiàn)的設(shè)備
     CBCentralManagerScanOptionSolicitedServiceUUIDsKey @[CBUDID] 掃描的指定服務(wù)UUID數(shù)組
     */
    // 停止掃描外圍設(shè)備
    [centralManager stopScan];
    // 連接外圍設(shè)備
    [centralManager connectPeripheral:peripheral options:@{}];
    /*
     CBConnectPeripheralOptionNotifyOnConnectionKey     @(BOOL) 是否彈出提示框(在后臺(tái)連接上設(shè)備)
     CBConnectPeripheralOptionNotifyOnDisconnectionKey  @(BOOL) 是否彈出提示框(在后臺(tái)斷開(kāi)連接設(shè)備)
     CBConnectPeripheralOptionNotifyOnNotificationKey   @(BOOL) 是否彈出提示框(在后臺(tái)接受到數(shù)據(jù)時(shí))
    */
    // 斷開(kāi)連接外圍設(shè)備
    [centralManager cancelPeripheralConnection:peripheral];\


    /*
     CBCentralManagerRestoredStatePeripheralsKey
     CBCentralManagerRestoredStateScanServicesKey
     CBCentralManagerRestoredStateScanOptionsKey
    */
    // CBPeripheral:周邊設(shè)備
    CBPeripheral *per=[CBPeripheral new];
    // dele<CBPeripheralDelegate>
    [per setDelegate:nil];
    // name(readOnly)
    NSString *perName=per.name;
    // state(readOnly)
    CBPeripheralState perState=per.state;
    /*
     CBPeripheralStateDisconnected      未連接
     CBPeripheralStateConnecting        連接中
     CBPeripheralStateConnected         已連接
     CBPeripheralStateDisconnecting     斷開(kāi)連接中
     */
    // services(readOnly)
    NSArray<CBService *> *perServiceArr=per.services;
    // RSSI
    [per readRSSI];
    // 發(fā)現(xiàn)服務(wù)(根據(jù)ServiceID)
    [per discoverServices:@[[CBUUID UUIDWithString:@"SERVICE ID"]]];
    // 尋找特征(根據(jù)charactID service)
    [per discoverIncludedServices:@[charactUUID] forService:service];
    // 贮配?
    [per discoverCharacteristics:@[charactUUID] forService:service];
    // 從外圍設(shè)備讀取數(shù)據(jù)(從相應(yīng)特征值),調(diào)用didUpdateValue
    [per readValueForCharacteristic:charact];
    // 向特征寫(xiě)入值
    [per writeValue:[NSData data] forCharacteristic:charact type:CBCharacteristicWriteWithResponse];
    // CBCharacteristicWriteWithoutResponse/CBCharacteristicWriteWithResponse
    // 從外圍設(shè)備讀取數(shù)據(jù)塞赂,并訂閱特征(打開(kāi)通知泪勒,一有數(shù)據(jù)就獲取,false則關(guān)閉),調(diào)用didUpdateNoti
    [per setNotifyValue:true forCharacteristic:charact];
    // 發(fā)現(xiàn)描述
    [per discoverDescriptorsForCharacteristic:charact];
    // 讀取值從描述
    [per readValueForDescriptor:descriptor];
    // 向描述寫(xiě)入值
    [per writeValue:[NSData data] forDescriptor:descriptor];
    // CBService:服務(wù)
    CBService *service=[CBService new];
    // 發(fā)送此服務(wù)的周邊設(shè)備(readOnly)
    CBPeripheral *servicePeripheral=service.peripheral;
    // primary/secondary(readOnly)
    BOOL serviceIsPrimary=service.isPrimary;
    // 已經(jīng)發(fā)現(xiàn)的服務(wù)列表?(readOnly)
    NSArray<CBService *> *serviceIncludedServiceArr=service.includedServices;
    // 已經(jīng)發(fā)現(xiàn)的特征列表?(readOnly)
    NSArray<CBCharacteristic *> *serviceCharacteristicArr=service.characteristics;
    // 特征
    CBCharacteristic *charact=[CBCharacteristic new];
    // 此特征屬于哪個(gè)service(readOnly)
    CBService *charactService=charact.service;
    // 特征類(lèi)型(readOnly)
    CBCharacteristicProperties charactProperties=charact.properties;
    /*
     CBCharacteristicPropertyBroadcast                      廣播
     CBCharacteristicPropertyRead                           讀數(shù)據(jù)
     CBCharacteristicPropertyWriteWithoutResponse           寫(xiě)數(shù)據(jù)不要響應(yīng)
     CBCharacteristicPropertyWrite                          寫(xiě)數(shù)據(jù)
     CBCharacteristicPropertyNotify                         通知
     CBCharacteristicPropertyIndicate
     CBCharacteristicPropertyAuthenticatedSignedWrites
     CBCharacteristicPropertyExtendedProperties
     */
    // 數(shù)據(jù)(readOnly)
    NSData *charactData=charact.value;
    // 改特征已經(jīng)被發(fā)現(xiàn)的描述(readOnly)
    NSArray<CBDescriptor *> *charactDescriptorArr=charact.descriptors;
    // 該特征是否正在通知(readOnly)
    BOOL charactIsNotifying=charact.isNotifying;
    // CBDescriptor:描述
    CBDescriptor *descriptor=[CBDescriptor new];
    // 該描述屬于哪個(gè)特征(readOnly)
    CBCharacteristic *descriptorCharacteristic=descriptor.characteristic;
    // value(readOnly)
    id descriptorValue=descriptor.value;
2. WiFi
WiFi通訊
       利用WiFi信號(hào)讓手機(jī)和智能硬件設(shè)備進(jìn)行數(shù)據(jù)傳輸處理的一種方式减途。
通訊原理
       使用Socket(套接字酣藻,Scoket = IP地址(找到哪臺(tái)電腦即服務(wù)器)+端口號(hào)(找到服務(wù)器上的哪個(gè)應(yīng)用))進(jìn)行UDP(一對(duì)多)通訊
構(gòu)成
      (1)路由器(提供WiFi信號(hào)曹洽,作為中間者負(fù)責(zé)轉(zhuǎn)發(fā)傳遞數(shù)據(jù))
      (2)硬件(手機(jī)/硬件設(shè)備鳍置,數(shù)據(jù)發(fā)送與接收方)


3種使用類(lèi)型
       (1)手機(jī)(連上外部設(shè)備的WiFi)直接與外部設(shè)備(裝有WiFi芯片)建立連接
       (2)手機(jī)和外部設(shè)備都連接上同一路由器
       (3)云端WiFi通訊(大趨勢(shì)) ,手機(jī)<->服務(wù)器<->硬件,解決了前兩種方法必須連上同一WiFi的局限送淆。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末税产,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌辟拷,老刑警劉巖撞羽,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異衫冻,居然都是意外死亡诀紊,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)隅俘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)邻奠,“玉大人,你說(shuō)我怎么就攤上這事为居÷笛纾” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵蒙畴,是天一觀的道長(zhǎng)贰镣。 經(jīng)常有香客問(wèn)我,道長(zhǎng)膳凝,這世上最難降的妖魔是什么碑隆? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮鸠项,結(jié)果婚禮上干跛,老公的妹妹穿的比我還像新娘。我一直安慰自己祟绊,他們只是感情好楼入,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著牧抽,像睡著了一般嘉熊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上扬舒,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天阐肤,我揣著相機(jī)與錄音,去河邊找鬼讲坎。 笑死孕惜,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的晨炕。 我是一名探鬼主播衫画,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼瓮栗!你這毒婦竟也來(lái)了削罩?” 一聲冷哼從身側(cè)響起瞄勾,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎弥激,沒(méi)想到半個(gè)月后进陡,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡微服,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年趾疚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片以蕴。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡盗蟆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出舒裤,到底是詐尸還是另有隱情喳资,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布腾供,位于F島的核電站仆邓,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏伴鳖。R本人自食惡果不足惜节值,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望榜聂。 院中可真熱鬧搞疗,春花似錦、人聲如沸须肆。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)豌汇。三九已至幢炸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拒贱,已是汗流浹背宛徊。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留逻澳,地道東北人闸天。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像斜做,于是被迫代替她去往敵國(guó)和親苞氮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355