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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

iOS蓝牙开发

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

CoreBluetooth詳解

CoreBluetooth框架的核心其實是兩個東西,peripheral和central, 可以理解成外設和中心。

圖中兩組api分別對應不同的業務場景,左側叫做中心模式,就是以你的app作為中心,連接其他的外設的場景,而右側稱為外設模式,使用手機作為外設別其他中心設備操作的場景

關于藍牙開發的一些重要的理論概念:

1、服務(services):藍牙外設對外廣播的時候一定會有一個服務,有些時候也可以是有多個服務,服務下面包含一些特性,服務可以理解成一個模塊的窗口;
2、特征(characteristic):特征存在于服務下面的,一個服務下面可以有多個特征,特征可以理解成具體實現功能的窗口,一般的特性都會有value,也就是特征值,是特征和外界交互的最小單位;
3、UUID:藍牙上的唯一標示符,為了區分不同設備、服務及特征,就用UUID來表示。

CBCentralMannager 中心模式

以手機(app)作為中心,連接其他外設的場景。詳細流程如下:

步驟1.建立一個Central Manager實例進行藍牙管理

步驟2.搜索外圍設備

步驟3.連接外圍設備

步驟4.獲得外圍設備的服務

步驟5.獲得服務的特征

步奏6.從外圍設備讀數據(直接讀取和訂閱兩種方法)

步驟7.給外圍設備發送數據

#import "ViewController.h" #import #define kPeripheralName @"Kenshin Cui's Device" //外圍設備名稱 #define kServiceUUID @"C4FB2349-72FE-4CA2-94D6-1F3CB16331EE" //服務的UUID #define kCharacteristicUUID @"6A3E4B28-522D-4B3B-82A9-D5E2004534FC" //特征的UUID@interface ViewController ()@property (strong,nonatomic) CBPeripheralManager *peripheralManager;//外圍設備管理器@property (strong,nonatomic) NSMutableArray *centralM;//訂閱此外圍設備特征的中心設備@property (strong,nonatomic) CBMutableCharacteristic *characteristicM;//特征 @property (weak, nonatomic) IBOutlet UITextView *log; //日志記錄@end @implementation ViewController #pragma mark - 控制器視圖事件 - (void)viewDidLoad {[super viewDidLoad]; }#pragma mark - UI事件 - (IBAction)startClick:(UIBarButtonItem *)sender {//創建中心設備管理器并設置當前控制器視圖為代理_centralManager=[[CBCentralManager alloc]initWithDelegate:self queue:nil]; }#pragma mark - CBCentralManager代理方法 //中心服務器狀態更新后 -(void)centralManagerDidUpdateState:(CBCentralManager *)central{switch (central.state) {case CBPeripheralManagerStatePoweredOn:NSLog(@"BLE已打開.");[self writeToLog:@"BLE已打開."];//掃描外圍設備 // [central scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:kServiceUUID]] options:@{CBCentralManagerScanOptionAllowDuplicatesKey:@YES}];[central scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey:@YES}];break;default:NSLog(@"此設備不支持BLE或未打開藍牙功能,無法作為外圍設備.");[self writeToLog:@"此設備不支持BLE或未打開藍牙功能,無法作為外圍設備."];break;} } /*** 發現外圍設備** @param central 中心設備* @param peripheral 外圍設備* @param advertisementData 特征數據* @param RSSI 信號質量(信號強度)*/ -(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{NSLog(@"發現外圍設備...");[self writeToLog:@"發現外圍設備..."];//停止掃描[self.centralManager stopScan];//連接外圍設備if (peripheral) {//添加保存外圍設備,注意如果這里不保存外圍設備(或者說peripheral沒有一個強引用,無法到達連接成功(或失敗)的代理方法,因為在此方法調用完就會被銷毀if(![self.peripherals containsObject:peripheral]){[self.peripherals addObject:peripheral];}NSLog(@"開始連接外圍設備...");[self writeToLog:@"開始連接外圍設備..."];[self.centralManager connectPeripheral:peripheral options:nil];}} //連接到外圍設備 -(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{NSLog(@"連接外圍設備成功!");[self writeToLog:@"連接外圍設備成功!"];//設置外圍設備的代理為當前視圖控制器peripheral.delegate=self;//外圍設備開始尋找服務[peripheral discoverServices:@[[CBUUID UUIDWithString:kServiceUUID]]]; } //連接外圍設備失敗 -(void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{NSLog(@"連接外圍設備失敗!");[self writeToLog:@"連接外圍設備失敗!"]; }#pragma mark - CBPeripheral 代理方法 //外圍設備尋找到服務后 -(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{NSLog(@"已發現可用服務...");[self writeToLog:@"已發現可用服務..."];if(error){NSLog(@"外圍設備尋找服務過程中發生錯誤,錯誤信息:%@",error.localizedDescription);[self writeToLog:[NSString stringWithFormat:@"外圍設備尋找服務過程中發生錯誤,錯誤信息:%@",error.localizedDescription]];}//遍歷查找到的服務CBUUID *serviceUUID=[CBUUID UUIDWithString:kServiceUUID];CBUUID *characteristicUUID=[CBUUID UUIDWithString:kCharacteristicUUID];for (CBService *service in peripheral.services) {if([service.UUID isEqual:serviceUUID]){//外圍設備查找指定服務中的特征[peripheral discoverCharacteristics:@[characteristicUUID] forService:service];}} } //外圍設備尋找到特征后 -(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{NSLog(@"已發現可用特征...");[self writeToLog:@"已發現可用特征..."];if (error) {NSLog(@"外圍設備尋找特征過程中發生錯誤,錯誤信息:%@",error.localizedDescription);[self writeToLog:[NSString stringWithFormat:@"外圍設備尋找特征過程中發生錯誤,錯誤信息:%@",error.localizedDescription]];}//遍歷服務中的特征CBUUID *serviceUUID=[CBUUID UUIDWithString:kServiceUUID];CBUUID *characteristicUUID=[CBUUID UUIDWithString:kCharacteristicUUID];if ([service.UUID isEqual:serviceUUID]) {for (CBCharacteristic *characteristic in service.characteristics) {if ([characteristic.UUID isEqual:characteristicUUID]) {//情景一:通知/*找到特征后設置外圍設備為已通知狀態(訂閱特征):*1.調用此方法會觸發代理方法:-(void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error*2.調用此方法會觸發外圍設備的訂閱代理方法*/[peripheral setNotifyValue:YES forCharacteristic:characteristic];//情景二:讀取 // [peripheral readValueForCharacteristic:characteristic]; // if(characteristic.value){ // NSString *value=[[NSString alloc]initWithData:characteristic.value encoding:NSUTF8StringEncoding]; // NSLog(@"讀取到特征值:%@",value); // }}}} } //特征值被更新后 -(void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{NSLog(@"收到特征更新通知...");[self writeToLog:@"收到特征更新通知..."];if (error) {NSLog(@"更新通知狀態時發生錯誤,錯誤信息:%@",error.localizedDescription);}//給特征值設置新的值CBUUID *characteristicUUID=[CBUUID UUIDWithString:kCharacteristicUUID];if ([characteristic.UUID isEqual:characteristicUUID]) {if (characteristic.isNotifying) {if (characteristic.properties==CBCharacteristicPropertyNotify) {NSLog(@"已訂閱特征通知.");[self writeToLog:@"已訂閱特征通知."];return;}else if (characteristic.properties ==CBCharacteristicPropertyRead) {//從外圍設備讀取新值,調用此方法會觸發代理方法:-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error[peripheral readValueForCharacteristic:characteristic];}}else{NSLog(@"停止已停止.");[self writeToLog:@"停止已停止."];//取消連接[self.centralManager cancelPeripheralConnection:peripheral];}} } //更新特征值后(調用readValueForCharacteristic:方法或者外圍設備在訂閱后更新特征值都會調用此代理方法) -(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{if (error) {NSLog(@"更新特征值時發生錯誤,錯誤信息:%@",error.localizedDescription);[self writeToLog:[NSString stringWithFormat:@"更新特征值時發生錯誤,錯誤信息:%@",error.localizedDescription]];return;}if (characteristic.value) {NSString *value=[[NSString alloc]initWithData:characteristic.value encoding:NSUTF8StringEncoding];NSLog(@"讀取到特征值:%@",value);[self writeToLog:[NSString stringWithFormat:@"讀取到特征值:%@",value]];}else{NSLog(@"未發現特征值.");[self writeToLog:@"未發現特征值."];} }#pragma mark - 屬性 -(NSMutableArray *)peripherals{if(!_peripherals){_peripherals=[NSMutableArray array];}return _peripherals; }#pragma mark - 私有方法 /*** 記錄日志** @param info 日志信息*/ -(void)writeToLog:(NSString *)info{self.log.text=[NSString stringWithFormat:@"%@\r\n%@",self.log.text,info]; }@end

CBPeripheralManager 外設模式

使用手機作為外設連接其他中心設備操作的場景。
PS:因為蘋果設備的安全性和封閉性,蘋果設備不能通過與其他設備藍牙鏈接進行文件傳輸等功能,所以在iOS與藍牙開發的編程中是CBCentralMannager 中心模式編程居多.

1 建立外設角色
2 設置本地外設的服務和特征
3 發布外設和特征
4 廣播服務
5 響應中心的讀寫請求
6 發送更新的特征值,訂閱中心

#import "ViewController.h" #import #define kServiceUUID @"C4FB2349-72FE-4CA2-94D6-1F3CB16331EE" //服務的UUID #define kCharacteristicUUID @"6A3E4B28-522D-4B3B-82A9-D5E2004534FC" //特征的UUID@interface ViewController ()@property (strong,nonatomic) CBCentralManager *centralManager;//中心設備管理器 @property (strong,nonatomic) NSMutableArray *peripherals;//連接的外圍設備 @property (weak, nonatomic) IBOutlet UITextView *log;//日志記錄@end @implementation ViewController #pragma mark - 視圖控制器方法 - (void)viewDidLoad {[super viewDidLoad]; }#pragma mark - UI事件 //創建外圍設備 - (IBAction)startClick:(UIBarButtonItem *)sender {_peripheralManager=[[CBPeripheralManager alloc]initWithDelegate:self queue:nil]; } //更新數據 - (IBAction)transferClick:(UIBarButtonItem *)sender {[self updateCharacteristicValue]; }#pragma mark - CBPeripheralManager代理方法 //外圍設備狀態發生變化后調用 -(void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral{switch (peripheral.state) {case CBPeripheralManagerStatePoweredOn:NSLog(@"BLE已打開.");[self writeToLog:@"BLE已打開."];//添加服務[self setupService];break;default:NSLog(@"此設備不支持BLE或未打開藍牙功能,無法作為外圍設備.");[self writeToLog:@"此設備不支持BLE或未打開藍牙功能,無法作為外圍設備."];break;} } //外圍設備添加服務后調用 -(void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error{if (error) {NSLog(@"向外圍設備添加服務失敗,錯誤詳情:%@",error.localizedDescription);[self writeToLog:[NSString stringWithFormat:@"向外圍設備添加服務失敗,錯誤詳情:%@",error.localizedDescription]];return;}//添加服務后開始廣播NSDictionary *dic=@{CBAdvertisementDataLocalNameKey:kPeripheralName};//廣播設置[self.peripheralManager startAdvertising:dic];//開始廣播NSLog(@"向外圍設備添加了服務并開始廣播...");[self writeToLog:@"向外圍設備添加了服務并開始廣播..."]; } -(void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(NSError *)error{if (error) {NSLog(@"啟動廣播過程中發生錯誤,錯誤信息:%@",error.localizedDescription);[self writeToLog:[NSString stringWithFormat:@"啟動廣播過程中發生錯誤,錯誤信息:%@",error.localizedDescription]];return;}NSLog(@"啟動廣播...");[self writeToLog:@"啟動廣播..."]; } //訂閱特征 -(void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic{NSLog(@"中心設備:%@ 已訂閱特征:%@.",central,characteristic);[self writeToLog:[NSString stringWithFormat:@"中心設備:%@ 已訂閱特征:%@.",central.identifier.UUIDString,characteristic.UUID]];//發現中心設備并存儲if (![self.centralM containsObject:central]) {[self.centralM addObject:central];}/*中心設備訂閱成功后外圍設備可以更新特征值發送到中心設備,一旦更新特征值將會觸發中心設備的代理方法:-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error*/// [self updateCharacteristicValue]; } //取消訂閱特征 -(void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic{NSLog(@"didUnsubscribeFromCharacteristic"); } -(void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(CBATTRequest *)request{NSLog(@"didReceiveWriteRequests"); } -(void)peripheralManager:(CBPeripheralManager *)peripheral willRestoreState:(NSDictionary *)dict{NSLog(@"willRestoreState"); } #pragma mark -屬性 -(NSMutableArray *)centralM{if (!_centralM) {_centralM=[NSMutableArray array];}return _centralM; }#pragma mark - 私有方法 //創建特征、服務并添加服務到外圍設備 -(void)setupService{/*1.創建特征*///創建特征的UUID對象CBUUID *characteristicUUID=[CBUUID UUIDWithString:kCharacteristicUUID];//特征值 // NSString *valueStr=kPeripheralName; // NSData *value=[valueStr dataUsingEncoding:NSUTF8StringEncoding];//創建特征/** 參數* uuid:特征標識* properties:特征的屬性,例如:可通知、可寫、可讀等* value:特征值* permissions:特征的權限*/CBMutableCharacteristic *characteristicM=[[CBMutableCharacteristic alloc]initWithType:characteristicUUID properties:CBCharacteristicPropertyNotify value:nil permissions:CBAttributePermissionsReadable];self.characteristicM=characteristicM; // CBMutableCharacteristic *characteristicM=[[CBMutableCharacteristic alloc]initWithType:characteristicUUID properties:CBCharacteristicPropertyRead value:nil permissions:CBAttributePermissionsReadable]; // characteristicM.value=value;/*創建服務并且設置特征*///創建服務UUID對象CBUUID *serviceUUID=[CBUUID UUIDWithString:kServiceUUID];//創建服務CBMutableService *serviceM=[[CBMutableService alloc]initWithType:serviceUUID primary:YES];//設置服務的特征[serviceM setCharacteristics:@[characteristicM]];/*將服務添加到外圍設備*/[self.peripheralManager addService:serviceM]; } //更新特征值 -(void)updateCharacteristicValue{//特征值NSString *valueStr=[NSString stringWithFormat:@"%@ --%@",kPeripheralName,[NSDate date]];NSData *value=[valueStr dataUsingEncoding:NSUTF8StringEncoding];//更新特征值[self.peripheralManager updateValue:value forCharacteristic:self.characteristicM onSubscribedCentrals:nil];[self writeToLog:[NSString stringWithFormat:@"更新特征值:%@",valueStr]]; } /*** 記錄日志** @param info 日志信息*/ -(void)writeToLog:(NSString *)info{self.log.text=[NSString stringWithFormat:@"%@\r\n%@",self.log.text,info]; } @end

藍牙連接發送數據的流程圖

lightblue怎么用

OTA(空中升級)

將手機作為外圍設備開發

iOS淺析藍牙設備之服務器(外圍設備)

APP被作為外設

遇到的坑

所以得知道 設備廣播的的UUID
或者用下面代碼搜索藍牙

[self.centralManager scanForPeripheralsWithServices:nil options:nil];

一般藍牙連接失敗我們會實現以下方法

// 連接失敗(但不包含超時,系統沒有超時處理) - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {if (error && self.delegate && [self.delegate respondsToSelector:@selector(centralTool:connectFailure:)]) {[self.delegate centralTool:self connectFailure:error];} }- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {[self autoConnect]; }

但是當廣播設備的藍牙斷開再想重連的話還要實現下面這個方法

- (void)peripheral:(CBPeripheral *)peripheral didModifyServices:(NSArray<CBService *> *)invalidatedServices{[self.centralManager connectPeripheral:peripheral options:nil];// 注意保留 Peripheral 的引用self.lastConnectedPeripheral = peripheral;[self startTimer]; }

只有這樣才能實現斷開藍牙重開藍牙秒連

另外,有時候要提高搜索效率的話,可以過濾藍牙的名字

NSString *name = peripheral.name;if (name.length == 0) {return;}NSLog(@"name === %@",name);NSString *string = [NSString stringWithFormat:@"已發現 peripheral: %@ rssi: %@, UUID: %@ advertisementData: %@ ", peripheral, RSSI, peripheral.identifier, advertisementData];NSLog(@"string == %@",string);if ([name rangeOfString:@"Berry"].location == NSNotFound) {return;}// NSString *kCBAdvDataLocalName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey]; // if ([kCBAdvDataLocalName rangeOfString:@"Berry"].location == NSNotFound) { // return; // }

不過要注意 上文代碼中的name 和 kCBAdvDataLocalName 是不同的
一個是藍牙設備的名字, 一個是廣播的名字

//添加服務后開始廣播 //廣播設置NSDictionary *dic=@{CBAdvertisementDataLocalNameKey:MyDeviceName,CBAdvertisementDataServiceUUIDsKey:@[[CBUUID UUIDWithString:@"FFE0"]]}; //廣播設置[self.peripheralManager startAdvertising:dic];//開始廣播

第一個坑中設置UUID找不到的問題就是,需要在上述代碼中設置UUID
網上找的大部分資料都是關于如何設置中心設備的,外設的比較少,所以這里容易出錯

不過,如果這塊都設置了,對于快速精準找到目標藍牙服務是大有裨益的,也會減少耗電量,提高響應速度等等。

總結

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

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