處理ANCS設備連接綁定問題

ANCS(Apple Notification Center Service,蘋果通知中心)的目的是提供給藍牙外設一種簡單、方便的獲取iOS設備通知信息的方式。使得藍牙手環,手錶可以接收到來自iPhone的來電、短信及QQ、微信等應用的通知消息。

如果你已經能夠連接普通藍牙,初次面對ANCS設備可能會有以下問題:

問題一:遵循ANCS協議的的設備會直接和系統相連,即使殺掉應用,連接還是存在的。而如果藍牙設備處於連接狀態,它不會被掃描到,怎麼再次連接呢?

在Core Bluetooth framework裏提供了兩個方法,用於獲取已連接的設備

//通過傳入的peripherals.identifier返回與系統連接的已知設備數組
- (NSArray<CBPeripheral *> *)retrievePeripheralsWithIdentifiers:(NSArray<NSUUID *> *)identifiers;
//通過傳入設備的serviceID返回已連接的設備數組
- (NSArray<CBPeripheral *> *)retrieveConnectedPeripheralsWithServices:(NSArray<CBUUID *> *)serviceUUIDs;
複製代碼

我們就可以通過這兩個方法,獲取已連接設備,並建立重連。參考代碼:

NSArray *peripherals = [central retrieveConnectedPeripheralsWithServices:@[serviceUUID]];
if (peripherals.count > 0) {
    CBPeripheral *peripheral = [peripherals firstObject];
    peripheral.delegate = self;
    self.peripheral = peripheral;//**關鍵**需要轉存外設值,才能發起連接
    [central connectPeripheral:self.peripheral options:nil];
} else {
    [central scanForPeripheralsWithServices:@[serviceUUID] options:nil];
}
複製代碼

根據不同的使用情況,可能會有不同的掃描,連接的邏輯,蘋果提供了一個流程圖:

問題二:有綁定和解除功能,如何處理兩者的關係

首先我們要知道,不能通過代碼,斷開ANCS設備與系統之間的連接,那麼如果我們想解除設備的綁定,只能控制設備與APP之間的斷開。

綁定

再回看上面提到的蘋果提供的兩個獲取已連接設備的方法,一個是通過serviceUUID,它可以返回同一類型的設備列表;一個是通過設備UUID,它在一定情況下就是唯一的(如果設備名唯一,這裏可以使用設備名),返回的是唯一設備。那麼我們就可以利用UUID的唯一性,作爲綁定的標示,存到NSUserDefault裏面,對於未綁定的設備通過serviceUUID去獲取設備列表。參考代碼:

NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
NSString *uuidString = [userDefault objectForKey:RWBLE_BANDIDENTIFI_ID];
NSArray *peripherals;
if (uuidString) {
    //通過uuid獲取連接設備
    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:uuidString];
    peripherals = [self.centralManager retrievePeripheralsWithIdentifiers:@[uuid]];
}else{
    //通過serviceUUID獲取連接設備
    peripherals = [self.centralManager retrieveConnectedPeripheralsWithServices:@[[CBUUID UUIDWithString:ST_SERVICE_UUID]]];
}
/* peripherals connect code */
複製代碼

解綁

不能使ANCS設備與系統連接斷開,那麼我們就在程序裏銷燬這個外設對象,這樣APP與藍牙設備的連接通訊就不存在了,造成了一種斷開的感覺。參考代碼:

//解綁設備
- (void)unbindDevice{
    [self disconnect];//通知app,設備已經斷開

     NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
     [userDefault removeObjectForKey:RWBLE_BANDIDENTIFI_ID];//銷燬uuid
     self.peripheral = nil;
}
複製代碼

這麼寫看似已經解決問題了,但是會出現一種情況:解綁了設備,殺掉應用,再次進入設備還是能連上。why?因爲雖然沒有了UUID,但進入程序會通過serviceUUID再次獲取連接。

這時可以在掃面做一個判斷,是否剛解綁過設備。可以是個BOOL值,綁定和初始綁定爲NO,解綁操作改爲YES。如果剛解綁過設備,就直接返回不做後面的掃描操作,這樣就解決了上面的問題。這個比較簡單,就不列具體代碼了。

參考文檔: Best Practices for Interacting with a Remote Peripheral Device

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章