與遠程外設交互的最佳實踐
Core Bluetooth框架使中央端的很多事務對你的應用程序透明,也就是,你的應用程序已經控制了,并負責實現大多數中央角色方面,設備掃描,連接,探索和與遠程外設數據交互。這個章節提供指導和最佳實踐為以負責任的方式治理控制水平,特別是當給一個iOS設備開發你的應用程序時。
注意無線的使用和功耗
當開發一個與藍牙低功耗設備交互的應用程序時,記住藍牙低功耗在通信過程中會享用你的設備無線來在空中傳遞信號。因為其它形式的無線通信可能需要用你的設備無線--例如,Wi-Fi,經典藍牙,和其它應用程序使用藍牙低功耗--開發你的應用程序最小化使用無線。
當給一個iOS設備開發一個應用程序時最小化無線的使用是特別重要的,因為無線的使用不利于電池的壽命。下面的指導方針將幫你成為一個你設備的無線的好公民。因此,你的應用程序將執行得更好,你的設備的電池將持續更長的時間。
只有當你需要的時候才去掃描設備
當你調用CBCentralManager
類的scanForPeripheralsWithServices:options:
方法來發現正在廣播服務的外設時,你的中央設備會使用無線來監聽正在廣播的設備,直到你明確告訴它停止。
除非你需要發現更多的設備,在你已經發現了你想要連接的設備的時候停止掃描其它設備。用CBCentralManager
類的stopScan
方法來停止掃描其它的設備,在Connecting to a Peripheral Device After You've Discovered It中可見。
只有在必要的時候才指定CBCentralManagerScanOptionAllowDuplicatesKey
選項
遠程外設可能會每秒發送多個廣播包給在監聽的中央來宣布它們的存在,當你使用scanForPeripheralsWithService:options:
方法正在掃描設備時,這個方法的默認行為是合并多個發現的廣播外設成單個發現事件--也就是說,沒發現一個新的外設,中央管理者會調用它的代理對象的centralManager:didDiscoverPeripheral:advertisementData:RSSI:
方法,不管它接受到了多少廣播包。當一個已經準備發現的外設廣播數據改變時中央管理者也會調用這個代理方法。
如果你想要改變這個默認行為,你可以在調用scanForPeripheralsWithServices:options:
方法時指定CBCentralManagerScanOptionAllowDuplicatesKey
常量作為掃描選項。當你這樣做,每次中央接受到外設的廣播包時都會形成一個發現事件。關掉默認的行為對某些情況是有用的,例如在外設上啟動與外設的連接(使用外設接受信號強度指示值(RSSI)).也就是說,記住指定這個掃描選項不利于電池的壽命和應用程序的性能。因此,只有在特殊使用情況下需要的時候才指定這個掃描選項。
明智地探索一個外設的數據
當你在開發一個應用程序來實現一種特定的使用情況時一個外設可能有比你可能感興趣的更多的服務和特征。發現所有的外設服務和相關的特征會給你的應用程序性能和電池壽命帶來不好的影響。因此,你應該查看和發現你的應用程序需要的服務和特征。
例如,想象你已經連接了一個有很多有效服務的外設,但是你的應用程序只需要訪問它們中的兩個。你可以只查看和發現這兩個服務,通過調用CBPeripheral
類的discoverServices:
方法傳遞的參數是它們的服務的UUIDs的數組(使用CBUUID
對象表示),就像:
[peripheral discoverServices:@[firstServiceUUID, secondServiceUUID]];
在你發現了你感興趣的兩個服務之后,你可以類似地發現你只感興趣的服務的特征。再一次,通過調用CBPeripheral
類的discoverCharacteristics:forService:
方法傳遞參數是你想要發現的特征的UUIDs組成的數組(對于每個服務)。
訂閱經常改變的特征值
正如Retrieving Value of a Characteristic中描述,有兩種方式獲得一個特征值:
- 你可以通過每次需要值的時候調用
readValueForCharacteristic:
方法來明確地獲取特征值 - 你可以通過調用
setNotifyValue:forCharacteristic:
方法來訂閱特征值,一旦值發生了變化會接受到一個從外設發來的通知。
當指定的特征值經常發生改變時訂閱這個特征值是一個好的實踐。有一個例子關于訂閱特征值,請看Subscribing to a Characteristic's Value 。
當你已經有了你想要的所有數據的時候斷開與設備的連接
當你有一個不再需要的連接的時候通過斷開與外設的連接可以有助于減少你的應用程序的無線使用。你應該在下面的兩種情況下斷開與外設的連接:
- 你訂閱的所有特征值已經停止發送了通知(你可以通過訪問特征的
isNotifying
屬性來決定特征值是否正在通知) - 你已經從外設那里獲取到了你想要的所有數據
在這兩種情況下,取消訂閱你可能有的并斷開與外設的連接。你可以通過調用setNotifyValue:forCharacteristic:
方法來取消訂閱一個特征值,設置第一個參數為NO
。你可以通過調用CBCentralManager
類的cancelPeripheralConnection:
方法取消與一個外設的連接。就像:
[myCentralManager cancelPeripheralConnection:peripheral];
注意:
cancelPeripheralConnection:
方法是不閉塞的,你嘗試斷開連接的外設的還沒發出的命令可能沒執行完。因為其它的應用程序可能仍然與該外設連接著,取消一個本地的連接不能保證底層的物理鏈路立即斷開。從你的應用程序角度來看,外設是斷開的,和中央角色會調用它的代理對象的centralManager:didDisconnectPeripheral:error:
方法。
重新連接外設
使用Core Bluetooth框架,有三種方式可以用來重新連接外設,你可以:
- 獲得外設的列表-在過去你發現或已經連接的外設-使用
retrievePeripheralsWithIdentifiers:
方法。如果這個外設你能在該列表中查找到,嘗試連接。這個重連的選項在Retrieving a List of Known Peripherals中有描述。 - 使用
retrieveConnectedPeripheralsWithServices:
方法獲得當前與系統連接的外設列表。如果這個外設你能在該列表中查找到,連接它到你的本地應用程序。這個重連的選項在Retrieving a List of Connected Peripherals中有描述。 - 使用
scanForPeripheralsWithServices:options:
方法掃描和發現外設。如果你找到它了,連接它。這一步在Discover Peripheral Devices That Are Advertising和Connecting to a Peripheral Device After You're Discovered It中都有描述。
視使用情況而定,你想重連它但又不想每次都必須掃描和發現相同的外設,你可能想要嘗試使用第一個選項來重連它來代替。如圖5-1所示,它們在上面列出的順序中有可能嘗試每一個選項的重連工作流程。
注意:你決定嘗試的重連選項的數目,和你這樣做的順序,可能由你的應用程序嘗試滿足的使用情況而有所不同。例如,你可能決定根本就不使用第一個連接的選項,或者你可能決定嘗試使用第一個和第二個選項。
獲取已知的外設列表
第一次你發現一個外設,系統會用一個標識符(一個UUID,用NSUUID
對象表示)來標識這個外設。然后你可以存儲這個標識符(使用NSUserDefaults
類的資源),然后用CBCentralManager
類的retrievePeripheralsWithIdentifiers:
方法嘗試重連這個外設。下面描述了一個方式來使用這個方法來重連一個你已經之前連接過的外設。
當你的應用程序啟動時,調用retrievePeripheralsWithIdentifiers:
方法,通過你之前發現和連接過的外設(你已經保存了它的標識符)的標識符號來獲得一個數組,就像:
knownPeripherals = [myCentralManager retrievePeripheralsWithIdentifiers:savedIdentifiers];
中央管理者嘗試匹配你提供的之前發現外設的標識符號然后返回一個包含CBPeripheral
對象的數組結果。如果發現的都沒有匹配上,這個數組是空的,你應該嘗試使用另外兩種重連方式。如果這個數組不是空的,讓用戶在界面上選擇嘗試重新連接哪一個外設。
當用戶選擇了一個外設,通過調用CBCentralManager
類的connectPeripheral:options:
方法嘗試連接它。如果這個外設依然能有效地被連接上,中央管理者會調用它的代理對象的centralManager:didConnectPeripheral:
方法,這個外設就被成功重新連接上了。
注意:一個外設可能因為一些原因在被連接的時候無效。對于這種情況,外設可能不在中央附近。另外,一些藍牙低功耗設備使用一個隨機的設備地址周期性的改變。因此,即使設備在附近,設備的地址可能已經改變了自從它被系統發現的上一次。在這種情況下,你嘗試連接的
CBPeripheral
對象不符合真實的外設。如果你因為它的設備地址已經改變了而不能重新連接上這個外設,你必須使用scanForPeripheralsWithServices:options:
方法重新發現它。關于隨機設備地址的更多信息,請看藍牙4.0規范,和Bluetooth Accessory Design Guidelines for Apple Produces。
獲取已經連接的外設列表
另外一種方式來重新連接外設是通過檢查看你發現已經與系統(例如,被其它的應用程序)連接的哪個外設.你可以通過調用CBCentralManager
類的retrieveConnectedPeripheralsWithServices:
方法,會返回一個裝有當前與系統連接的外設用CBPeripheral
對象表示的數組。
因為可能當前與系統連接的外設不止一個,你可以通過有CBUUID
對象(表示服務的UUIDs)的數組來獲取只與當前系統連接的和包含一些被你指定的UUIDs的標識的服務的外設。如果沒有外設與當前系統連接,這個數組是空的,你應該嘗試用其它的兩種重連方法。如果這個數組不是空的,讓用戶在界面上嘗試連接哪個外設。
假定用戶發現和選擇了想要的外設,通過調用CBCentralManager
類的connectPeripheral:options:
方法來讓它與你的應用程序連接。(即使這個設備已經與系統連接了,你仍然必須連接它到你的應用程序來開始探索和與它交互)。當這個本地連接建立了,中央管理者會調用它的代理對象的centralManager:didConnectPeripheral:
方法,這個外設就成功地被重新連接了。
-- 翻譯的文檔地址:Best Practices for Interacting With a Remote Peripheral Device