目前APP與硬件模塊之間的通信有幾種模式:藍牙連接模式、WiFi連接模式(Socket或HTTP服務器)、DLNA音視頻共享(iOS上也可以使用AirPlay)。最近在項目中,測試了APP通過藍牙與外設硬件連接的功能,整理了一些相關的開發、實現和測試方法,在這裡與大家分享。
藍牙基礎知識
1. iOS台下藍牙開發可以使用 MFI(ExternalAccessory 框架) 或 BLE (CoreBluetooth 框架) 進行,但實際開發中基本都使用 CoreBluetooth 框架,因為它功能更強大,支持藍牙4.0标準。
2. 藍牙4.0 BLE (Bluetooth low energy) :它的優點在于傳輸快,耗電低,但傳輸數據有限,雖然這個傳輸字節大小硬件工程師可調,但也不會太大。
3. CoreBluetooth框架的核心是peripheral和 central, 可以理解成外設和中心,發起連接的是central,被連接的設備為 peripheral,它們是一組相對概念。比如,當手機去連接控制藍牙耳機時,你的手機就是central,當手機藍牙被另一個手機連接并為其提供服務時就是peripheral。
4. Service和Characteristic:藍牙設備通過GATT協議定義的數據通訊方式。一個 peripheral可以提供多種 服務Service,一種Service 又可以包含多個不同的 特征Characteristic。特征就是具體鍵值對,提供數據的地方。每個特征屬性分為讀、寫、通知等幾種方式。
5. central通過peripheral 的 Characteristic 來讀寫外設的數據,和獲取通知。Peripheral廣播自己的Service和characteristic,Central訂閱某一個具體的characteristic,Peripheral就和Central之間通過characteristic建立了一個雙向的數據通道
6. 外設peripheral、服務Service、特征characteristic之間的關系:
7. UUID:藍牙上的唯一标示符,為了區分不同服務和特征,就用UUID來表示。
藍牙的兩種工作模式
1. 中心模式
建立中心
掃描外設(discover)
連接外設(connect) 連接失敗、連接斷開、連接成功
掃描外設中的服務和特征(discover)4.1 獲取外設的 services4.2 獲取外設的 Characteristics,獲取Characteristics的值,獲 Characteristics的 Descriptor 和Descriptor 的值 與外設做數據交互(explore and interact) 訂閱 Characteristic 的通知斷開連接(disconnect)
2. 外設模式
啟動一個 Peripheral 管理對象
本地 Peripheral 設置服務,特性,描述,權限等等
Peripheral 發送廣播
設置處理訂閱、取消訂閱、讀 characteristic、寫 characteristic 的委托方法
3. 藍牙設備的工作狀态
準備(standby)
廣播(advertising)
監聽掃描(Scanning
發起連接(Initiating)
已連接(Connected)
藍牙連接的開發實現
這裡以手機端作為central,以藍牙設備作為peripheral,藍牙設備連接的開發實現主要包括以下步驟:
1. 導入蘋果系統藍牙框架
#import
2. 遵循兩個藍牙框架相關的協議
<cbcentralmanagerdelegate,cbperipheraldelegate></cbcentralmanagerdelegate,cbperipheraldelegate>
3. 新建兩個實例屬性,一個特征屬性
@property (nonatomic, strong) CBCentralManager*centralManager; //中心管理者
@property (nonatomic, strong) CBPeripheral *peripheral; //連接到的外設
@property (nonatomic, strong) CBCharacteristic*characteristic; //特征
4. 初始化CBCentralManager,進行藍牙管理
- (void)viewDidLoad {
[superviewDidLoad];
self.centralManager= [[CBCentralManager alloc] initWithDelegate:selfqueue:dispatch_get_main_queue()]; //創建實例進行藍牙管理
}
//若中心管理者初始化之後就會觸發下面這個代理方法。該代理方法是用來判斷手機藍牙的狀态的
-(void)centralManagerDidUpdateState:(CBCentralManager *)central {
//藍牙可用,開始掃描外設
if(central.state == CBManagerStatePoweredOn) {
NSLog(@"藍牙可用");
//在中心管理者成功開啟之後再進行一些操作
//搜索掃描外設
//根據SERVICE_UUID來掃描外設,如果不設置SERVICE_UUID,則掃描所有藍牙設備
//[self.centralManagerstartAdvertising:@{CBAdvertisementDataServiceUUIDsKey:@[[CBUUIDUUIDWithString:SERVICE_UUID]]}];
[centralscanForPeripheralsWithServices:nil options:nil];
}
if(central.state== CBManagerStateUnsupported) {
NSLog(@"該設備不支持藍牙");
if(central.state == CBManagerStatePoweredOff) {
NSLog(@"藍牙已關閉");
if(central.state == CBManagerStateUnknown) {
NSLog(@"藍牙當前狀态不明确");
if(central.state == CBManagerStateUnauthorized) {
NSLog(@"藍牙未被授權");
5. 搜索外圍設備
//執行掃描動作之後,如果掃描到外設了,就會自動回調下面的協議方法
/** 發現符合要求的外設,回調 */
- (void)centralManager:(CBCentralManager*)central didDiscoverPeripheral:(CBPeripheral *)peripheraladvertisementData:(NSDictionary
NSLog(@"%@====",peripheral.name);
//根據外設名字有選擇性的篩選連接藍牙設備
if([peripheral.name hasPrefix:@"TEAMOSA"]) {
//在這裡對外設攜帶的廣播數據進行進一步的處理
if([self.peripheraNames containsObject:peripheral.name]) {
//如果數組中包含了就不再添加
return;
}
//添加到外設名字數組中
[self.peripheraNamesaddObject:peripheral.name];
//标記外設,讓它的生命周期與控制器的一緻
self.peripheral= peripheral;
//可以根據外設名字來過濾外設
//[central connectPeripheral:peripheral options:nil];
//連接外設
6. 連接外圍設備
//連接外圍設備,中心管理者連接外設成功,如果連接成功就會回調這個協議方法
/** 連接成功 */
- (void)centralManager:(CBCentralManager*)central didConnectPeripheral:(CBPeripheral *)peripheral{
//連接成功之後,可以進行服務和特性的發現。停止中心管理設備的掃描動作,要不然在你和已經連接好的外設進行數據溝通時,如果又有一個外設進行廣播且符合你的連接條件,那麼你的iOS設備也會去連接這個設備(因為iOS BLE4.0是支持一對多連接的),導緻數據的混亂。
//停止掃描動作
[self.centralManagerstopScan];
//設置外設的代理
peripheral.delegate= self;
//根據UUID來尋找服務
//[peripheral discoverServices:@[[CBUUID UUIDWithString:SERVICE_UUID]]];
//外設發現服務,傳nil代表不過濾,一次性讀出外設的所有服務
[peripheraldiscoverServices:nil];
NSLog(@"%s,line = %d, %@=連接成功", __FUNCTION__, __LINE__,peripheral.name);
//外設連接失敗
/** 連接失敗的回調 */
- (void)centralManager:(CBCentralManager*)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError*)error {
NSLog(@"%s,line = %d, %@=連接失敗", __FUNCTION__, __LINE__,peripheral.name);
//丢失連接 掉線
/** 斷開連接 */
- (void)centralManager:(CBCentralManager*)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(nullableNSError *)error {
NSLog(@"%s,line = %d, %@=斷開連接", __FUNCTION__, __LINE__,peripheral.name);
//斷開連接可以設置重新連接
[centralconnectPeripheral:peripheral options:nil];
以上,已經實現了APP端連接藍牙設備的功能,藍牙設備連接完成後,還可以對設備進行數據讀寫,包括:獲取外圍設備服務和特征;從外圍設備讀取數據;向外圍設備發送(寫入)數據等操作。這裡暫不具體展開。
APP鍊接藍牙設備的測試關注點
介紹了藍牙的基礎知識、APP連接藍牙設備的開發實現,接下來将介紹APP連接藍牙設備這一過程測試中需要關注的測試點(由于每種藍牙設備連接需求不同,開發實現上也會有細小差别,實際測試中可視具體開發邏輯進行調整):
1. APP掃描設備
①手機端藍牙不同設置下是否能正常掃描:藍牙打開、藍牙關閉;
②藍牙設備被掃描到并出現在可連接設備列表的條件:藍牙設備名稱與可連接的設備列表中的名稱匹配、設備處于廣播狀态;
藍牙設備與可連接的設備列表中名稱是否匹配:匹配、不匹配;
藍牙設備狀态(視具體硬件而定):待機狀态、廣播狀态、已連接狀态、藍牙設備操作中、數據傳輸中、關機狀态;
測試以上各種組合場景下,藍牙設備是否能正常掃描且出現在可連接設備列表;
③不同場景下,是否正常掃描:
一個手機同時掃描多個設備;
多個手機同時掃描同一個設備;
多個手機同時掃描多個設備;
④掃描過程中取消;
⑤掃描結果:掃描超時;未掃描到可連接設備,是否支持重試;掃描失敗;掃描成功;
2. 連接設備(APP端點擊可連接設備列表,連接藍牙設備)
①測試藍牙設備狀态變化後,不同狀态下是否可正常連接:待機狀态、廣播狀态、已連接狀态、藍牙設備操作中、數據傳輸中、關機狀态;
②連接結果的處理:連接成功、連接失敗、連接超時等;
③連接成功後的操作:APP其他操作、連接中斷、退到後台、殺掉APP等;
④其他場景:掃描到多個設備;
3. 斷開連接
①設備端斷開:設備關機、設備電量耗盡;
②APP端斷開:手動斷開、其他操作斷開連接;
4. 其他交互操作
①切換其他藍牙設備,是否正常連接;
②藍牙斷開後重新打開,支持自動連接;
③距離超出藍牙可檢測範圍,是否會斷開連接,再恢複到可檢測範圍,能否自動連接;
④手機端連接多個不同藍牙設備,各個設備功能是否都正常使用;
5. 連接成功後的數據傳輸
①功能上,APP端和藍牙設備端是否符合正常使用需求;
②性能上,APP與藍牙設備的交互是否滿足需求;
(本文隻讨論藍牙設備連接部分和具體數據傳輸部分的用例,大家可以擴展一下。)
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!