日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

iOS 蓝牙开发 swift (一)

發布時間:2023/12/20 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iOS 蓝牙开发 swift (一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

iOS 藍牙開發

    • 1.藍牙簡介
    • 2. 藍牙連接
      • 2.1 CoreBluetooth框架
      • 2.2 外設、服務、特征間的關系
      • 2.3 藍牙連接過程
      • 2.4 藍牙中心模式,外設模式
        • 2.4.1 藍牙中心模式
        • 2.4.2 藍牙外設模式
      • 2.5 藍牙設備狀態
      • 2.6 藍牙連接代碼實現

1.藍牙簡介

  • 藍牙模式簡介
    藍牙開發分為兩種模式,中心模式(central),和外設模式(peripheral)。一般來講,我們需要在軟件內連接硬件,通過連接硬件給硬件發送指令以完成一些動作的藍牙開發都是基于中心模式(central)模式的開發,也就是說我們開發的app是中心,我們要連接的硬件是外設。如果需要其他設備連接手機藍牙,并對手機進行一些操作,那就是基于外設模式(peripheral)的開發。 本次我們主要介紹的就是中心模式的藍牙開發

  • 設備簡介
    中心設備(CBCentralManager):iOS系統的手機等設備
    外圍設備(CBPeripheral):手環等第三方設備

  • 藍牙數據傳輸簡介
    將外圍設備(車輛)的數據傳送給中心設備(手機)時, 數據是經過兩層包裝的
    第一層是 Service(服務) , 可以是一個或多個, 比如車輛數據(服務)
    第二層是 Characteristic(特征) , 他提供了更多關于Service(服務)的數據, 例如車輛數據(服務)中包含了兩個數據, 分別是里程數據和續航數據, 這兩個就是車輛數據(服務)的具體數據(特征)

  • 具體操作簡介
    讀(read) , 寫(write) , 訂閱(notify)
    我們的目的是讀取設備中的數據(read) , 或者給設備寫入一定的數據(write)。有時候我們還想設備的數據變化的時候不需要我們手動去讀取這個值,需要設備自動通知我們它的值變化了,值是多少。把值告訴app,這個時候就需要訂閱這個特征了(notify)

  • 其他相關概念

  • 目前都使用的是低功耗藍牙4.0,藍牙外設必需為4.0及以上(2.0需要MFI認證),否則無法開發,藍牙4.0設施由于低耗電,所以也叫做BLE。
  • CoreBluetooth框架的核心其實是兩個東西,peripheral和central, 能了解成外設和中心,就是你的蘋果手機就是中心,外部藍牙稱為外設。
  • 服務和特征(service characteristic):簡而言之,外部藍牙中它有若干個服務service(服務你能了解為藍牙所擁有的可以力),而每個服務service下擁有若干個特征characteristic(特征你能了解為解釋這個服務的屬性)。
  • Descriptor(形容)使用來形容characteristic變量的屬性。例如,一個descriptor能規定一個可讀的形容,或者者一個characteristic變量可接受的范圍,或者者一個characteristic變量特定的單位。
  • 我們用的藍牙板塊是在淘寶買的, 大概十多元一個, ios大概每次能接受90個字節, 安卓大概每次能接收20個字節, 具體數字可可以會浮動, 應該是與藍牙板塊有關。
  • 2. 藍牙連接

    自己實踐的兩個藍牙demo:

  • OC 編寫的:Bluetooth4_configWifi
  • swifit編寫的:KYLBluetoothDemo_swift
  • 2.1 CoreBluetooth框架

    CoreBluetooth框架的核心其實是兩個東西,peripheral和central, 可以理解成外設和中心。對應他們分別有一組相關的API和類

    • 這兩組api分別對應不同的業務場景,左側叫做中心模式,就是以你的app作為中心,連接其他的外設的場景,而右側稱為外設模式,使用手機作為外設別其他中心設備操作的場景。
    • 服務和特征,特征的屬性(service and characteristic):
      每個設備都會有一些服務,每個服務里面都會有一些特征,特征就是具體鍵值對,提供數據的地方。每個特征屬性分為這么幾種:讀,寫,通知這么幾種方式。
    //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 };

    2.2 外設、服務、特征間的關系

    2.3 藍牙連接過程

  • 創建中心設備(CBCentralManager)
  • 中心設備開始掃描(scanForPeripherals)
  • 掃描到外圍設備之后, 自動調用中心設備的代理方法(didDiscoverPeripheral)
  • 如果設備過多, 可以將掃描到的外圍設備添加到數組
  • 開始連接, 從數組中過濾出自己想要的設備, 進行連接(connectPeripheral)
  • 連接上之后, 自動調用中心設備的代理方法(didConnectPeripheral), 在代理中, 進行查找外圍設備的服務(peripheral.discoverServices)
  • 查找到服務之后, 自動調用外圍設備的代理(didDiscoverServices), 可通過UUID,查找具體的服務,查找服務(discoverCharacteristics)
  • 查找到特征之后, 自動調用外圍設備的代理(didDiscoverCharacteristics), 通過UUID找到自己想要的特征, 讀取特征(readValueForCharacteristic)
  • 讀取到特征之后, 自動調用外設的代理方法(didUpdateValueForCharacteristic),在這里打印或者解析自己想要的特征值.
  • 2.4 藍牙中心模式,外設模式

    2.4.1 藍牙中心模式

    • 中心模式流程
  • 建立中心角色

  • 掃描外設(discover)

  • 連接外設(connect)

  • 掃描外設中的服務和特征(discover)
    4.1 獲取外設的services
    4.2 獲取外設的Characteristics,獲取Characteristics的值,獲取Characteristics的 Descriptor和Descriptor的值

  • 與外設做數據交互(explore and interact)

  • 訂閱Characteristic的通知

  • 斷開連接(disconnect)

  • 2.4.2 藍牙外設模式

    • 藍牙外設模式流程
  • 啟動一個Peripheral管理對象

  • 本地Peripheral設置服務,特性,描述,權限等等

  • Peripheral發送廣告

  • 設置處理訂閱、取消訂閱、讀characteristic、寫characteristic的委托方法

  • 2.5 藍牙設備狀態

    • 藍牙設備狀態
      待機狀態(standby):設備沒有傳輸和發送數據,并且沒有連接到任何設
      廣播狀態(Advertiser):周期性廣播狀態
      掃描狀態(Scanner):主動尋找正在廣播的設備
      發起鏈接狀態(Initiator):主動向掃描設備發起連接。
      主設備(Master):作為主設備連接到其他設備。
      從設備(Slave):作為從設備連接到其他設備。

    • 藍牙設備的五種工作狀態
      準備(standby)
      廣播(advertising)
      監聽掃描(Scanning
      發起連接(Initiating)
      已連接(Connected)

    2.6 藍牙連接代碼實現

  • 初始化
  • self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
  • 搜索掃描外圍設備
  • /*** -- 初始化成功自動調用* -- 必須實現的代理,用來返回創建的centralManager的狀態。* -- 注意:必須確認當前是CBCentralManagerStatePoweredOn狀態才可以調用掃描外設的方法:scanForPeripheralsWithServices*/ - (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表示默認掃描所有可見藍牙設備。-- 注意:第一個參數是用來掃描有指定服務的外設。然后有些外設的服務是相同的,比如都有FFF5服務,那么都會發現;而有些外設的服務是不可見的,就會掃描不到設備。-- 成功掃描到外設后調用didDiscoverPeripheral*/[self.centralManager scanForPeripheralsWithServices:nil options:nil];}break;default:break;} }#pragma mark 發現外設 - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary*)advertisementData RSSI:(NSNumber *)RSSI{NSLog(@"Find device:%@", [peripheral name]);if (![_deviceDic objectForKey:[peripheral name]]) {NSLog(@"Find device:%@", [peripheral name]);if (peripheral!=nil) {if ([peripheral name]!=nil) {if ([[peripheral name] hasPrefix:@"根據設備名過濾"]) {[_deviceDic setObject:peripheral forKey:[peripheral name]];// 停止掃描, 看需求決定要不要加 // [_centralManager stopScan];// 將設備信息傳到外面的頁面(VC), 構成掃描到的設備列表if ([self.delegate respondsToSelector:@selector(dataWithBluetoothDic:)]) {[self.delegate dataWithBluetoothDic:_deviceDic];}}}}} }
  • 連接外圍設備
  • // 連接設備(.h中聲明出去的接口, 一般在點擊設備列表連接時調用) - (void)connectDeviceWithPeripheral:(CBPeripheral *)peripheral {[self.centralManager connectPeripheral:peripheral options:nil]; }#pragma mark 連接外設--成功 - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{//連接成功后停止掃描,節省內存[central stopScan];peripheral.delegate = self;self.peripheral = peripheral;//4.掃描外設的服務/**-- 外設的服務、特征、描述等方法是CBPeripheralDelegate的內容,所以要先設置代理peripheral.delegate = self-- 參數表示你關心的服務的UUID,比如我關心的是"FFE0",參數就可以為@[[CBUUID UUIDWithString:@"FFE0"]].那么didDiscoverServices方法回調內容就只有這兩個UUID的服務,不會有其他多余的內容,提高效率。nil表示掃描所有服務-- 成功發現服務,回調didDiscoverServices*/[peripheral discoverServices:@[[CBUUID UUIDWithString:@"你要用的服務UUID"]]];if ([self.delegate respondsToSelector:@selector(didConnectBle)]) {// 已經連接[self.delegate didConnectBle];} }#pragma mark 連接外設——失敗 - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{NSLog(@"%@", error); }#pragma mark 取消與外設的連接回調 - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{NSLog(@"%@", peripheral); }
  • 獲得外圍設備的服務
  • #pragma mark 發現服務回調 - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{//NSLog(@"didDiscoverServices,Error:%@",error);CBService * __nullable findService = nil;// 遍歷服務for (CBService *service in peripheral.services){//NSLog(@"UUID:%@",service.UUID);if ([[service UUID] isEqual:[CBUUID UUIDWithString:@"你要用的服務UUID"]]){findService = service;}}NSLog(@"Find Service:%@",findService);if (findService)[peripheral discoverCharacteristics:NULL forService:findService]; }#pragma mark 發現特征回調 /**-- 發現特征后,可以根據特征的properties進行:讀readValueForCharacteristic、寫writeValue、訂閱通知setNotifyValue、掃描特征的描述discoverDescriptorsForCharacteristic。**/ - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{for (CBCharacteristic *characteristic in service.characteristics) {if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"你要用的特征UUID"]]) {/**-- 讀取成功回調didUpdateValueForCharacteristic*/self.characteristic = characteristic;// 接收一次(是讀一次信息還是數據經常變實時接收視情況而定, 再決定使用哪個) // [peripheral readValueForCharacteristic:characteristic];// 訂閱, 實時接收[peripheral setNotifyValue:YES forCharacteristic:characteristic];// 發送下行指令(發送一條)NSData *data = [@"硬件工程師給我的指令, 發送給藍牙該指令, 藍牙會給我返回一條數據" dataUsingEncoding:NSUTF8StringEncoding];// 將指令寫入藍牙[self.peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];}/**-- 當發現characteristic有descriptor,回調didDiscoverDescriptorsForCharacteristic*/[peripheral discoverDescriptorsForCharacteristic:characteristic];} }
  • 從外圍設備讀取數據
  • #pragma mark - 獲取值 - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{// characteristic.value就是藍牙給我們的值(我這里是json格式字符串)NSData *jsonData = [characteristic.value dataUsingEncoding:NSUTF8StringEncoding];NSDictionary *dataDic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];// 將字典傳出去就可以使用了 }#pragma mark - 中心讀取外設實時數據 - (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{if (characteristic.isNotifying) {[peripheral readValueForCharacteristic:characteristic];} else { NSLog(@"Notification stopped on %@. Disconnecting", characteristic);NSLog(@"%@", characteristic);[self.centralManager cancelPeripheralConnection:peripheral];} }
  • 給外圍設備發送(寫入)數據
  • // 上文中發現特征之后, 發送下行指令的時候其實就是向藍牙中寫入數據 // 例: // 發送檢查藍牙命令 - (void)writeCheckBleWithBle {_style = 1;// 發送下行指令(發送一條)NSData *data = [@"硬件工程師提供給你的指令, 類似于5E16010203...這種很長一串" dataUsingEncoding:NSUTF8StringEncoding];[self.peripheral writeValue:data forCharacteristic:self.characteristic type:CBCharacteristicWriteWithResponse]; }#pragma mark 數據寫入成功回調 - (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{NSLog(@"寫入成功");if ([self.delegate respondsToSelector:@selector(didWriteSucessWithStyle:)]) {[self.delegate didWriteSucessWithStyle:_style];} }
  • 停止掃描
  • #pragma mark 停止掃描外設 - (void)stopScanPeripheral{[self.centralManager stopScan]; }#pragma mark 掃描外設 - (void)scanDevice {if (_centralManager == nil) {self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];[_deviceDic removeAllObjects];} }
  • 斷開連接
  • #pragma mark 斷開連接 - (void)disConnectPeripheral{/**-- 斷開連接后回調didDisconnectPeripheral-- 注意斷開后如果要重新掃描這個外設,需要重新調用[self.centralManager scanForPeripheralsWithServices:nil options:nil];*/[self.centralManager cancelPeripheralConnection:self.peripheral]; }
  • 總結

    以上是生活随笔為你收集整理的iOS 蓝牙开发 swift (一)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。