ANCS(Apple Notification Center Service,蘋果通知中心)的目的是提供給藍牙外設一種簡單、方便的獲取iOS設備通知信息的方式。使得藍牙手環,手錶能夠接收到來自iPhone的來電、短信及QQ、微信等應用的通知消息。html
若是你已經可以鏈接普通藍牙,初次面對ANCS設備可能會有如下問題:數組
問題一:遵循ANCS協議的的設備會直接和系統相連,即便殺掉應用,鏈接仍是存在的。而若是藍牙設備處於鏈接狀態,它不會被掃描到,怎麼再次鏈接呢?微信
在Core Bluetooth framework裏提供了兩個方法,用於獲取已鏈接的設備app
//經過傳入的peripherals.identifier返回與系統鏈接的已知設備數組
- (NSArray<CBPeripheral *> *)retrievePeripheralsWithIdentifiers:(NSArray<NSUUID *> *)identifiers;
//經過傳入設備的serviceID返回已鏈接的設備數組
- (NSArray<CBPeripheral *> *)retrieveConnectedPeripheralsWithServices:(NSArray<CBUUID *> *)serviceUUIDs;
複製代碼
咱們就能夠經過這兩個方法,獲取已鏈接設備,並創建重連。參考代碼:ide
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];
}
複製代碼
根據不一樣的使用狀況,可能會有不一樣的掃描,鏈接的邏輯,蘋果提供了一個流程圖:ui
問題二:有綁定和解除功能,如何處理二者的關係spa
首先咱們要知道,不能經過代碼,斷開ANCS設備與系統之間的鏈接,那麼若是咱們想解除設備的綁定,只能控制設備與APP之間的斷開。code
再回看上面提到的蘋果提供的兩個獲取已鏈接設備的方法,一個是經過serviceUUID,它能夠返回同一類型的設備列表;一個是經過設備UUID,它在必定狀況下就是惟一的(若是設備名惟一,這裏可使用設備名),返回的是惟一設備。那麼咱們就能夠利用UUID的惟一性,做爲綁定的標示,存到NSUserDefault裏面,對於未綁定的設備經過serviceUUID去獲取設備列表。參考代碼:cdn
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與藍牙設備的鏈接通信就不存在了,形成了一種斷開的感受。參考代碼:htm
//解綁設備
- (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