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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

学习ios蓝牙技术,仿写lightblue

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

bluetooth

上一次我們研究完iBeacon,發現iBeacon是基于藍牙4.0的一個封裝而已。那么,今天我們來研究ios的藍牙4.0的應用。最出名的app當屬lightblue,我們不妨來仿寫一個lightblue,這樣基本的ios藍牙編程就算入門了。

基本理論

框架與概念

在ios中使用藍牙技術,會用到CoreBluetooth框架。

里面對設備有2個定義:周邊(peripeheral)設備 與 中央(central)設備。發送藍牙信號的是周邊設備,接收藍牙信號的是中央設備。

可以這樣理解,周邊設備是服務端,中央設備是客戶端。中央設備可以去搜索周邊有哪些服務端,可以選擇連接上其中一臺,進行信息獲取。

支持藍牙4.0的手機,可以作為周邊設備,也可以作為中央設備,但是不能同時既為周邊設備又為中央設備。

類解讀

中央設備用?CBCentralManager?這個類管理。

周邊設備用?CBPeripheralManager?這個類管理;

周邊設備里面還有服務類?CBService,服務里面有各種各樣的特性類?CBCharacteristic。

仿寫lightblue

基本流程

  • 假設我們有2臺以上可用設備。
  • 其中一臺作為調試機,用來搜索其它設備,并連接上去。所以,是中央設備central。
  • 其它設備設置為藍牙發射器,即是周邊設備peripheral。
  • 調試機先掃描周邊設備,用UITableView展示所掃描到的周邊設備。
  • 點擊其中一臺設備,進行連接connect。
  • 連接上后,獲取其中的所有服務services。
  • 對其中每個服務進行遍歷,獲取所有的特性Characteristic。
  • 讀取每個特性,獲取每個特性的值value。
  • 至此,lightblue基本的仿寫思路就清晰列出來了。

    1. 掃描設備

    先包含頭文件

    1 #import <CoreBluetooth/CoreBluetooth.h>

    然后添加協議?CBCentralManagerDelegate

    接著定義2個屬性, CBCentralManager用來管理我們的中央設備,NSMutableArray用來保存掃描出來的周邊設備。

    1 2 @property (nonatomic, strong) CBCentralManager *centralMgr; @property (nonatomic, strong) NSMutableArray *arrayBLE;

    中央設備創建很簡單,第一個參數代表?CBCentralManager?代理,第二個參數設置為nil,因為Peripheral Manager將Run在主線程中。如果你想用不同的線程做更加復雜的事情,你需要創建一個隊列(queue)并將它放在這兒。

    1 2 self.centralMgr = [[CBCentralManager alloc] initWithDelegate:self queue:nil]; self.arrayBLE = [[NSMutableArray alloc] init];

    實現centralManagerDidUpdateState。當Central Manager被初始化,我們要檢查它的狀態,以檢查運行這個App的設備是不是支持BLE。

    1 2 3 4 5 6 7 8 9 10 11 12 13 - (void)centralManagerDidUpdateState:(CBCentralManager *)central { switch (central.state) { case CBCentralManagerStatePoweredOn: [self.centralMgr scanForPeripheralsWithServices:nil options:nil]; break; default: NSLog(@"Central Manager did change state"); break; } }

    -scanForPeripheralsWithServices:options:方法是中央設備開始掃描,可以設置為特定UUID來指,來差找一個指定的服務了。我們需要掃描周邊所有設備,第一個參數設置為nil。

    當發起掃描之后,我們需要實現?centralManager:didDiscoverPeripheral:advertisementData:RSSI:?通過該回調來獲取發現設備。

    這個回調說明著廣播數據和信號質量(RSSI-Received Signal Strength Indicator)的周邊設備被發現。通過信號質量,可以用判斷周邊設備離中央設備的遠近。

    1 2 3 4 5 6 7 8 9 - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI { BLEInfo *discoveredBLEInfo = [[BLEInfo alloc] init]; discoveredBLEInfo.discoveredPeripheral = peripheral; discoveredBLEInfo.rssi = RSSI; // update tableview [self saveBLE:discoveredBLEInfo]; }

    BLEInfo是我新建的一個類,用來存儲周邊設備信息的,具體如下:

    1 2 3 4 5 6 @interface BLEInfo : NSObject @property (nonatomic, strong) CBPeripheral *discoveredPeripheral; @property (nonatomic, strong) NSNumber *rssi; @end

    保存周邊設備信息,并把它們顯示到UITableView上:

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 - (BOOL)saveBLE:(BLEInfo *)discoveredBLEInfo { for (BLEInfo *info in self.arrayBLE) { if ([info.discoveredPeripheral.identifier.UUIDString isEqualToString:discoveredBLEInfo.discoveredPeripheral.identifier.UUIDString]) { return NO; } } [self.arrayBLE addObject:discoveredBLEInfo]; [self.tableView reloadData]; return YES; }

    掃描到的周邊設備展示如下:

    掃描到的周邊設備

    2. 連接設備

    當我們點擊其中一個設備,嘗試進行連接。lightblue是點擊后就立馬連接的,然后在下一個UITableView來展示該周邊設備的服務與特性。

    而我是進入下一頁UITableView才開始連接,差別不大。但是注意的是,一定要把我們之前的self.centralMgr傳遞到下一頁的UITableView來使用,并且重新設置delegate。

    用來展示服務和特性的UITableViewController:

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #import <UIKit/UIKit.h> #import <CoreBluetooth/CoreBluetooth.h> @interface BLEInfoTableViewController : UITableViewController < CBPeripheralManagerDelegate, CBCentralManagerDelegate, CBPeripheralDelegate > @property (nonatomic, strong) CBCentralManager *centralMgr; @property (nonatomic, strong) CBPeripheral *discoveredPeripheral; // tableview sections,保存藍牙設備里面的services字典,字典第一個為service,剩下是特性與值 @property (nonatomic, strong) NSMutableArray *arrayServices; // 用來記錄有多少特性,當全部特性保存完畢,刷新列表 @property (atomic, assign) int characteristicNum; @end

    記得把之前的centrlMgr傳過來,記得要重新設置delegate:

    1 2 3 4 5 6 7 8 9 10 11 12 - (void)viewDidLoad { [super viewDidLoad]; [_centralMgr setDelegate:self]; if (_discoveredPeripheral) { [_centralMgr connectPeripheral:_discoveredPeripheral options:nil]; } _arrayServices = [[NSMutableArray alloc] init]; _characteristicNum = 0; }

    其中,

    [centralMgr connectPeripheral:discoveredPeripheral options:nil];

    就是中央設備向周邊設備發起連接。

    我們可以實現下面的函數,如果連接失敗,就會得到回調:

    1 2 3 4 - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error { NSLog(@"didFailToConnectPeripheral : %@", error.localizedDescription); }

    我們必須實現didConnectPeripheral,只要連接成功,就能回調到該函數,開始獲取服務。

    1 2 3 4 5 6 7 8 9 - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral { [self.arrayServices removeAllObjects]; [_discoveredPeripheral setDelegate:self]; [_discoveredPeripheral discoverServices:nil]; }

    discoverServices就是查找該周邊設備的服務。

    3. 獲取服務

    當找到了服務之后,就能進入didDiscoverServices的回調。我們把全部服務都保存起來。

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error { if (error) { NSLog(@"didDiscoverServices : %@", [error localizedDescription]); // [self cleanup]; return; } for (CBService *s in peripheral.services) { NSLog(@"Service found with UUID : %@", s.UUID); NSMutableDictionary *dic = [[NSMutableDictionary alloc] initWithDictionary:@{SECTION_NAME:s.UUID.description}]; [self.arrayServices addObject:dic]; [s.peripheral discoverCharacteristics:nil forService:s]; } }

    4. 獲取特性

    我們通過discoverCharacteristics來獲取每個服務下的特性,通過下面的回調來獲取。

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error { if (error) { NSLog(@"didDiscoverCharacteristicsForService error : %@", [error localizedDescription]); return; } for (CBCharacteristic *c in service.characteristics) { self.characteristicNum++; [peripheral readValueForCharacteristic:c]; } }

    5. 獲取特性值

    readValueForCharacteristic可以讀取特性的值。

    通過下面的回調,就能得到特性值。

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error { self.characteristicNum--; if (self.characteristicNum == 0) { [self.tableView reloadData]; } if (error) { NSLog(@"didUpdateValueForCharacteristic error : %@", error.localizedDescription); return; } NSString *stringFromData = [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding]; if ([stringFromData isEqualToString:@"EOM"]) { NSLog(@"the characteristic text is END"); // [peripheral setNotifyValue:NO forCharacteristic:characteristic]; // [self.centralMgr cancelPeripheralConnection:peripheral]; } for (NSMutableDictionary *dic in self.arrayServices) { NSString *service = [dic valueForKey:SECTION_NAME]; if ([service isEqual:characteristic.service.UUID.description]) { NSLog(@"characteristic.description : %@", characteristic.UUID.description); [dic setValue:characteristic.value forKey:characteristic.UUID.description]; } } }

    連接到周邊設備獲得的藍牙信息

    其它

    本來蘋果是提供了xcode5.0加ios7的模擬器來實現模擬器開啟藍牙的,本來連文章都給出了:https://developer.apple.com/library/ios/technotes/tn2295/_index.html

    后來蘋果把這文章給刪了,還把ios7模擬器支持開啟藍牙給去掉。

    那么,可以通過這個文章http://blog.csdn.net/zhenyu5211314/article/details/24399887,使用6.0的模擬器來調試。

    參考文章

    iOS CoreBluetooth 教程

    藍牙 BLE CoreBluetooth 初探

    藍牙4.0 For IOS

    總結

    以上是生活随笔為你收集整理的学习ios蓝牙技术,仿写lightblue的全部內容,希望文章能夠幫你解決所遇到的問題。

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