ios藍牙開發學習筆記(二)central角色的實現

本文轉載自:http://blog.csdn.net/swibyn/article/details/52096321

Performing Common Central Role Tasks

central角色的實現

central 角色需要完成的幾件事情,如搜索,連接,與peripheral交互數據。
peripheral 角色同樣需要完成幾件事情,如,發布和廣播服務,響應讀,寫,訂閱請求

本章中,你將學習如何完成central端的功能。
1,創建central manager 對象
2,發現和連接正在廣播的peripheral
3,瀏覽peripheral的數據
4,發送讀和寫請求到peripheral設備
5,訂閱characteristic的值

下一章你將學習如何開發peripheral角色的功能

Starting Up a Central Manager

創建Central manager對象

myCentralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:nil];'

在這里self設置成central角色的代理。dispath queue設置為nil,意味著central事件將交由main queue處理。

創建central manager時,會觸發centralManagerDidUpdateState: 代理方法。你必須實現這個代理。

Discovering Peripheral Devices That Are Advertising

搜索正在發送廣播的peripheral

[myCentralManager scanForPeripheralsWithServices:nil options:nil];

注意:如果第一個參數設置成nil,那么centralmanager會返回所有被發現的peripherals,在實際應用中,你應該給他賦值 CBUUID 對象數組。這樣只有有廣播這些uuid服務的peripheral才會被返回,

一旦發現peripheral,將觸發
centralManager:didDiscoverPeripheral:advertisementData:RSSi:
代理方法,如果你想連接這個peripheral,請使用強引用變量引用它,這樣系統就不會釋放掉它。

  • (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral
    advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
    NSLog(@"Discovered %@", peripheral.name);
    self.discoveredPeripheral = peripheral;
    ...

如果你想連接多個設備,你可以使用NSArray來管理他們。不管什么情況,一旦你找到所有你想要的設備,你應該停止掃描以便節省電量。

[myCentralManager stopScan];

Connecting to a Peripheral Device After You’ve Discovered It

連接peripheral

[myCentralManager connectPeripheral:peripheral options:nil];

如果連接成功,則會觸發centralManager:didConnectPeripheral:代理方法,與之通訊之前,你需要為它設置代理

  • (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
    NSLog(@"Peripheral connected");
    peripheral.delegate = self;
    ...

Discovering the Services of a Peripheral That You’re Connected To

查詢peripheral的服務

建立連接之后,就可以查詢數據,第一步就是查詢有哪些services。因為廣播包有大小限制,在廣播中可能沒有顯示全部的服務信息,這里你可以使用discoverServices: 來查詢所有的services。

[peripheral discoverServices:nil];

注意:實際開發中,你不應該傳值nil,因為這樣做會返回所有的services,包括那些你不需要的services,這樣做會浪費時間和電量。所以你應該傳遞你需要的uuids。

查找到所有的服務會觸發peripheral:didDiscoverServices:代理方法

  • (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
    for (CBService *service in peripheral.services) {
    NSLog(@"Discovered service %@", service);
    ...
    }
    ...

Discovering the Characteristics of a Service

查找characteristics

發現service之后,下一步就是查找characteristics

NSLog(@"Discovering characteristics for service %@", interestingService);
[peripheral discoverCharacteristics:nil forService:interestingService];

注意:實際開發中,不要傳nil,這樣做會返回所有的characteristics,包括那些你不感興趣的characteristics。這樣做即浪費時間又損耗電量。所以你應該傳你需要的uuids的值

查找到characteristics之后,會觸發peripheral:didDiscoverCharacteristicsForService:error:代理方法

  • (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
    for (CBCharacteristic *characteristic in service.characteristics) {
    NSLog(@"Discovered characteristic %@", characteristic);
    ...
    }
    ...

Retrieving the Value of a Characteristic

獲取數據

一個characteristic只包含一種信息數據。比如恒溫service下的溫度characteristic只包含當前溫度值,你可以通過讀取或訂閱來獲得這個值。

Reading the Value of a Characteristic

讀取characteristic的數據

NSLog(@"Reading value for characteristic %@", interestingCharacteristic);
[peripheral readValueForCharacteristic:interestingCharacteristic];

獲取到數據后peripheral調用peripheral:didUpdateValueForCharacteristic:error:代理方法

  • (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    NSData *data = characteristic.value;
    // parse the data as needed
... 

注意:并不是所有的characteristic都是可讀的,你可以通過 characteristic的 proterties屬性是否包含CBCharacteristicPropertyRead 常量來判斷是否可讀。在讀一個不可讀的characteristic的數據值,會在代理方法的error參數中體現異常信息

Subscribing to a Characteristic’s Value

訂閱characteristic的值

雖然通過readValueForCharacteristic: 可以有效獲取靜態值,但如果值是動態改變的,則最好使用訂閱的方法。當值變化時,自動獲得通知。
設置訂閱

[peripheral setNotifyValue:YES forCharacteristic:interestingCharacteristic];

訂閱的時候peripheral會調用peripheral:didUpdateNotificationStateForCharacteristic:error: 代理方法。如果訂閱失敗了,也可以通過這個方法查詢失敗的原因

  • (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    if (error) {
    NSLog(@"Error changing notification state: %@",[error localizedDescription]);
    }

注意:并不是所有的characteristics都可以訂閱,可以通過檢查characteristic的properties屬性是否包含CBCharacteristicPropertyNotify 或 CBCharacteristicPropertyIndicate常量來判斷是否可訂閱

Writing the Value of a Characteristic

寫數據

有時也是需要寫數據的,比如恒溫器,你需要設置目標溫度。如果characteristic是可寫的,那么你就可以調用writeValue:forCharacteristic:type: 方法來寫入數據。如下:

NSLog(@"Writing value for characteristic %@", interestingCharacteristic);
[peripheral writeValue:dataToWrite forCharacteristic:interestingCharacteristic type:CBCharacteristicWriteWithResponse];

當你寫數據時,你可以標明寫類型。上例中,寫類型是CBCharacteristicWriteWithResponse, 這種情況下,不管有沒有寫成功,peripheral都會通過代理通知你。你需要實現這個方法以便處理異常情況。

  • (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    if (error) {
    NSLog(@"Error writing characteristic value: %@",[error localizedDescription]);
    }
    ...

如果你設置的寫類型是CBCharacteristicWriteWithoutResponse, 那么寫操作會以更有效的方式執行,但不保證寫成功,并且不會有報告。peripheral不會通知任何回調。

注意:characteristic可能只支持特定的寫類型,或不支持寫操作。你可以通過檢查properties屬性是否包含CBCharacteristicPropertyWriteWithoutResponse 或 CBCharacteristicPropertyWrite 來判斷。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 這里我們具體說明一下中心模式的應用場景。主設備(手機去掃描連接外設,發現外設服務和屬性,操作服務和屬性的應用。一般...
    丶逝水流年閱讀 2,288評論 3 4
  • iOS連接外設的代碼實現流程 1. 建立中心角色 2. 掃描外設(discover) 3. 連接外設(connec...
    UILabelkell閱讀 2,448評論 2 4
  • 首先進一則廣告: 藍牙技術聯盟(Bluetooth SIG)2010年7月7日宣布,正式采納藍牙4.0核心規范(B...
    L澤閱讀 1,472評論 3 4
  • 有時候真的很好奇朋友在我們生活中到底是一個怎樣的角色? 三個人的朋友真的很難去維持對于我來說是一種困難 每天看著兩...
    慕容夜閱讀 127評論 0 0
  • (1) 對面年輕貌美的姑娘低聲地說:“我跟男友分手了。” “太好了!”我禁不住這樣叫好。 認識這姑娘已經有一段時間...
    奧特霧漫劉閱讀 639評論 0 2