iOS對(duì)于ANCS設(shè)備的處理

1.什么是ANCS?

ANCS是Apple Notification Center Service的簡稱,中文為蘋果通知中心服務(wù)落包。
ANCS是蘋果讓周邊藍(lán)牙設(shè)備(手環(huán)、手表等)可以通過低功耗藍(lán)牙訪問IOS設(shè)備(iphone摊唇、ipad等)上的各類通知提供的一種簡單方便的機(jī)制咐蝇。

ANCS是基于BLE協(xié)議中的通用屬性協(xié)議(Generic Attribute Profile,GATT)協(xié)議實(shí)現(xiàn)的,他是GATT協(xié)議的一個(gè)子集巷查。在ANCS協(xié)議中有序,IOS設(shè)備作為gatt-server,而周邊設(shè)備作為gatt client來連接和使用server提供的其他services。

詳細(xì)的可以參考官網(wǎng)上的解釋ANCS spec

2.帶來的影響是什么岛请?

目前iOS這邊關(guān)于藍(lán)牙的開發(fā)大多都是基于Ble來實(shí)現(xiàn)的旭寿,對(duì)連接斷開有較深使用經(jīng)驗(yàn)的人都知道,iOS藍(lán)牙這邊的Ble關(guān)于斷連重新連接模塊都是用的懶加載(再次連上同一個(gè)mac地址的ble設(shè)備崇败,底層沒有重新獲取特征值盅称,只是從緩存里讀了一份給到上層)

所以ANCS帶來的影響是:

  • 1.無法從代碼層面斷開BLE連接了。

既然無法斷開后室,那就意味著一旦連上了就無法讓別的手機(jī)去搜索到缩膝,而且殺死當(dāng)前連上的應(yīng)用后轴脐,也無法通過常規(guī)的手段(centerManager.scanForPeripherals(withServices: nil, options: nil))去搜索到設(shè)備义图。

  • 2.業(yè)務(wù)流程設(shè)計(jì)上變得用戶體驗(yàn)很糟糕

3.如何解決?

  • 1.目前除了手動(dòng)解除綁定以外卵史,沒有其他的方法可以解除綁定
  • 2.iOS提供了 **central.retrievePeripherals(withIdentifiers:[uuid]) **的方法來獲取已連接上的ANCS設(shè)備

以下提供了一個(gè)demo來感受一下整個(gè)過程:

import Foundation
import CoreBluetooth
class BLEManager: NSObject,CBCentralManagerDelegate,CBPeripheralDelegate{
    lazy var centerManager:CBCentralManager = {
        CBCentralManager(delegate: self, queue: DispatchQueue.main)
    }()
    var myPeripheral:CBPeripheral?
    private var list:[CBPeripheral] = []
    override init() {
        super.init()
    }
    func start(){
        centerManager.scanForPeripherals(withServices: nil, options: nil)
        print("?? Need to hasPerfix your ble device's name or it maybe found nothing")
        DispatchQueue.main.asyncAfter(deadline: .now()+2, execute: {
            if let item = self.list.first {
                if item.state == .disconnected {
                    self.centerManager.connect(item, options: nil)
                }
            }
        })
    }
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        switch central.state {
        case .unknown:
            break
        case .resetting:
            break
        case .unsupported:
            break
        case .unauthorized:
            break
        case .poweredOff:
            break
        case .poweredOn:
            centerManager.scanForPeripherals(withServices: nil, options: nil)
        @unknown default:
            break
        }
    }
    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
        if ((peripheral.name?.hasPrefix("AC701N_")) != nil){
            if peripheral.name == "AC701N_GJ" {
                centerManager.stopScan()
                list.append(peripheral)
                print("Did found:\n\(peripheral)")
            }
        }
    }
    func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
        self.myPeripheral = peripheral
        self.myPeripheral?.delegate = self
        self.myPeripheral?.discoverServices(nil)
    }
    func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
        print("disconnect Ble in this application !")
        print("The Ble ANCS device is alway here,you can watch it in system setting")
        let uuid = UUID(uuid: peripheral.identifier.uuid)
        let array = central.retrievePeripherals(withIdentifiers:[uuid])
        for item in array {
            print("Now the ble is founded in here:\n\(item)")
            DispatchQueue.main.asyncAfter(deadline: .now()+10) {
                print("Here is to reconnect by 10 sec.")
                self.centerManager.connect(item, options: nil)
            }
        }
    }
    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
        guard let services = peripheral.services else{
            return
        }
        for service in services {
            if service.uuid.uuidString == "AE00" {
                peripheral.discoverCharacteristics(nil, for: service)
            }
        }
    }
    func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
        guard let charts = service.characteristics else { return }
        for chart in charts {
            if chart.uuid.uuidString == "AE01" {
                print("get wirte chart");
            }
            if chart.uuid.uuidString == "AE02" {
                print("get read chart")
            }
        }
        print("Please make sure pair in your phone ,it will disconnect by 10 sec.")
        DispatchQueue.main.asyncAfter(deadline: .now()+10) {
            print("go to cancel connect BLE")
            self.centerManager.cancelPeripheralConnection(peripheral)
        }
    }
}

運(yùn)行起來:

class ViewController: UIViewController {
    var mgr = BLEManager()
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        mgr.start()
    }
}

log分析

2022-04-01 12:00:37.131809+0800 BleConnect[683:73634] [CoreBluetooth] API MISUSE: <CBCentralManager: 0x282755320> can only accept this command while in the powered on state
?? Need to hasPerfix your ble device's name or it maybe found nothing
Did found:
<CBPeripheral: 0x2822540b0, identifier = A790557A-3B84-644B-B3AF-E8AC733D7089, name = AC701N_GJ, mtu = 0, state = disconnected>
get wirte chart
get read chart
Please make sure pair in your phone ,it will disconnect by 10 sec.
go to cancel connect BLE
disconnect Ble in this application !
The Ble ANCS device is alway here,you can watch it in system setting
Now the ble is founded in here:
<CBPeripheral: 0x2822540b0, identifier = A790557A-3B84-644B-B3AF-E8AC733D7089, name = AC701N_GJ, mtu = 23, state = disconnected>
Here is to reconnect by 10 sec.
get wirte chart
get read chart
Please make sure pair in your phone ,it will disconnect by 10 sec.
go to cancel connect BLE
disconnect Ble in this application !
The Ble ANCS device is alway here,you can watch it in system setting
Now the ble is founded in here:
<CBPeripheral: 0x2822540b0, identifier = A790557A-3B84-644B-B3AF-E8AC733D7089, name = AC701N_GJ, mtu = 23, state = disconnected>

最后注意的點(diǎn)

  • 1.設(shè)備通過A應(yīng)用連接手機(jī)贡避,A應(yīng)用內(nèi)無法通過API直接斷開設(shè)備痛黎,當(dāng)殺死應(yīng)用后,設(shè)備會(huì)處于一直連接著手機(jī)的情況刮吧。
    這個(gè)時(shí)候只能通過A應(yīng)用retrieveconnectedperipher去搜索出來舅逸,重新進(jìn)行連接。
  • 2.在情景1的A應(yīng)用殺死時(shí)設(shè)備還處于連接手機(jī)系統(tǒng)皇筛,B應(yīng)用/其他應(yīng)用通過retrieveconnectedperipher搜索出來設(shè)備琉历,但不可以獲取設(shè)備的service。
  • 3.在同一應(yīng)用,同一次連接BLE下旗笔,如果設(shè)備Mac不變彪置,短期內(nèi)多次發(fā)起斷連請(qǐng)求,iOS系統(tǒng)不會(huì)去重復(fù)請(qǐng)求設(shè)備的Service蝇恶,讀到的僅僅是緩存拳魁。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市撮弧,隨后出現(xiàn)的幾起案子潘懊,更是在濱河造成了極大的恐慌,老刑警劉巖贿衍,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件授舟,死亡現(xiàn)場離奇詭異,居然都是意外死亡贸辈,警方通過查閱死者的電腦和手機(jī)释树,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來擎淤,“玉大人奢啥,你說我怎么就攤上這事∽炻#” “怎么了桩盲?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長席吴。 經(jīng)常有香客問我正驻,道長,這世上最難降的妖魔是什么抢腐? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮襟交,結(jié)果婚禮上迈倍,老公的妹妹穿的比我還像新娘。我一直安慰自己捣域,他們只是感情好啼染,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著焕梅,像睡著了一般迹鹅。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上贞言,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天斜棚,我揣著相機(jī)與錄音,去河邊找鬼。 笑死弟蚀,一個(gè)胖子當(dāng)著我的面吹牛蚤霞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播义钉,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼昧绣,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了捶闸?” 一聲冷哼從身側(cè)響起夜畴,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎删壮,沒想到半個(gè)月后贪绘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡醉锅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年兔簇,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片硬耍。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡垄琐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出经柴,到底是詐尸還是另有隱情狸窘,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布坯认,位于F島的核電站翻擒,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏牛哺。R本人自食惡果不足惜陋气,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望引润。 院中可真熱鬧巩趁,春花似錦、人聲如沸淳附。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽奴曙。三九已至别凹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間洽糟,已是汗流浹背炉菲。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來泰國打工堕战, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人颁督。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓践啄,卻偏偏與公主長得像,于是被迫代替她去往敵國和親沉御。 傳聞我的和親對(duì)象是個(gè)殘疾皇子屿讽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容