iOS藍(lán)牙開發(fā)之掃描外設(shè)

分階段了解:

  1. 掃描
  2. 連接
  3. 發(fā)現(xiàn)服務(wù)和特征,寫入或讀取數(shù)據(jù)

掃描類

BTScanner

這個(gè)類是對(duì)CBCentralManager類中scanForPeripherals方法的封裝.而掃描到的外設(shè)會(huì)通過CBCentralManagerDelegate中的代理方法centralManager(_: didDiscover: advertisementData: rssi:)實(shí)時(shí)的回調(diào)出來

首先說一下這兩個(gè)方法的用途及參數(shù)介紹:

/*
 * withServices
      1.指定掃描外設(shè)的ServiceUUID,一般是和外設(shè)開發(fā)同事協(xié)商好的,所有設(shè)備都共用這一個(gè),是由外設(shè)在廣播時(shí)初始化傳入的,并告知中心設(shè)備
      2.這里也可傳nil,表示掃描附近所有設(shè)備,不建議傳nil
 * options:傳入字典類型
 
        默認(rèn)值為false表示不會(huì)重復(fù)掃描已經(jīng)發(fā)現(xiàn)的設(shè)備
        key:CBCentralManagerScanOptionAllowDuplicatesKey
        value:true
        
        你想掃描的目標(biāo)設(shè)備它所包含的serviceUUID數(shù)組
        key:CBCentralManagerScanOptionSolicitedServiceUUIDsKey
        value:[CBUUID]
        
 */
centralManager.scanForPeripherals(withServices: nil, options:nil)

可在CBCentralManagerDelegate的代理方法centralManagerDidUpdateState(_ central:)中調(diào)用此掃描方法,因?yàn)樵诔跏蓟疌BCentralManager后會(huì)自動(dòng)調(diào)用此代理方法,而后需手動(dòng)調(diào)用掃描方法開始掃描,做到效率最高,此代理方法在用戶改變藍(lán)牙狀態(tài)后,會(huì)被反復(fù)調(diào)用,為了避免重復(fù)操作,需要對(duì)掃描方法做一些處理.

  1. 添加一個(gè)定時(shí)器,用于在過了超時(shí)時(shí)間后,自動(dòng)停止掃描外設(shè),節(jié)約用戶的電量
  2. 添加一個(gè)標(biāo)志位busy表示此時(shí)正在掃描中

開始掃描外設(shè)

func scan(duration:TimeInterval) throws {
        guard !busy else { throw BikeScannerError.busy }
        guard centralManager != nil else { throw BikeScannerError.noCentralManagerSet }
        busy = true
        centralManager.scanForPeripherals(withServices: configuration.servicesUUIDs, options:[CBCentralManagerScanOptionAllowDuplicatesKey: true])
        timer = Timer.scheduledTimer(timeInterval: duration, target: self, selector: #selector(timerElapsed), userInfo: nil, repeats: false)
}

結(jié)束掃描的方法

func endScan() -> Void {
        centralManager.stopScan()
        busy = false 
        if let timer = timer {
            timer.invalidate()
            //成員變量scanHandlers是一個(gè)閉包scanHandlers?.completionHandler(discoveries)
        }
        discoveries.removeAll()
    }

調(diào)用掃描方法后,就會(huì)自動(dòng)調(diào)用下面這個(gè)代理方法

/*
 * central:中心設(shè)備
 * peripheral:發(fā)現(xiàn)的外設(shè)
 * advertisementData:掃描到外設(shè)廣播的數(shù)據(jù)
 * rssi:外設(shè)的信號(hào)強(qiáng)度
 */
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber)

如果外設(shè)是手機(jī)設(shè)備,那么這個(gè)外設(shè)僅可以通過advertisementData發(fā)送包含兩個(gè)字段的數(shù)據(jù),通過上面的回調(diào)方法,接收廣播數(shù)據(jù):

[
CBAdvertisementDataLocalNameKey:"我是外設(shè)的名字",
CBAdvertisementDataServiceUUIDsKey:[serviceUUID]
]

所以第一步需要新建個(gè)模型(BTDiscovery)將掃描回調(diào)的信息存起來

struct BTDiscovery {
    var advertisementData: [String : Any]
    var RSSI: NSNumber
    var peripheral:CBPeripheral
    
    //外設(shè)的名字
    var localName:String? {
        return advertisementData[CBAdvertisementDataLocalNameKey] as? String
    }
    
    //服務(wù)id
    var uuid:Array<CBUUID>? {
        return advertisementData[CBAdvertisementDataServiceUUIDsKey] as? Array<CBUUID>
    }
    
    //檢索目標(biāo)設(shè)備是否以約定字符串命名 比如: "Bluetooth1234"
    func hasPrefix(_ peripheralName:String) -> Bool {
        if let name = localName, name.hasPrefix(peripheralName) {
            return true
        }
        else{
            return false
        }
    }
}

extension BTDiscovery: Hashable, Equatable {
        var hashValue: Int {
        return peripheral.identifier.hashValue
    }
}

func ==(lhs:BTDiscovery, rhs:BTDiscovery) -> Bool {
    return lhs.peripheral == rhs.peripheral
}

接下來在回調(diào)方法中完成初始化,并存入成員變量discoveries數(shù)組中:

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
        //用于避免重復(fù)掃描的標(biāo)志位,后面會(huì)說到用處
        guard busy else { return }
        
        let remotePeripheral = BikePeripheral(peripheral)
        let discovery = BikeDiscovery(advertisementData: advertisementData, remotePeripheral: remotePeripheral, RSSI: Int(RSSI))
        
        if discovery.hasPrefix("BT") {
             discovery.peripheral.start(withConfiguration: configuration)
             //通過信號(hào)強(qiáng)度來過濾掉一些設(shè)備
             if discovery.RSSI < 1 && discovery.RSSI > -75 {
                //成員變量scanHandlers是一個(gè)閉包
                scanHandlers?.progressHandler?(self, discovery)           
                }
             discoveries.insert(discovery)
        }
            
    }

BikePeripheral是對(duì)CBPeripheral的再次封裝,在發(fā)現(xiàn)服務(wù)和特征,寫入或讀取數(shù)據(jù)小節(jié)中會(huì)講到,此處可忽略

其中變量scanHandlers聲明如下:

private var scanHandlers:(progressHandler:ScanProgressHandler?, completionHandler:ScanCompletionHandler)?

下篇將介紹藍(lán)牙連接類,戳這里
具體代碼請(qǐng)參考GitHub鏈接

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末佃声,一起剝皮案震驚了整個(gè)濱河市艺智,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌圾亏,老刑警劉巖十拣,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異志鹃,居然都是意外死亡夭问,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門曹铃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缰趋,“玉大人,你說我怎么就攤上這事∶匮” “怎么了味抖?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)灰粮。 經(jīng)常有香客問我仔涩,道長(zhǎng),這世上最難降的妖魔是什么谋竖? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任红柱,我火速辦了婚禮,結(jié)果婚禮上蓖乘,老公的妹妹穿的比我還像新娘锤悄。我一直安慰自己,他們只是感情好嘉抒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布零聚。 她就那樣靜靜地躺著,像睡著了一般些侍。 火紅的嫁衣襯著肌膚如雪隶症。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天岗宣,我揣著相機(jī)與錄音蚂会,去河邊找鬼。 笑死耗式,一個(gè)胖子當(dāng)著我的面吹牛胁住,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播刊咳,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼彪见,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了娱挨?” 一聲冷哼從身側(cè)響起余指,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎跷坝,沒想到半個(gè)月后酵镜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡探孝,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年笋婿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片顿颅。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡缸濒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情庇配,我是刑警寧澤斩跌,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站捞慌,受9級(jí)特大地震影響耀鸦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜啸澡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一袖订、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧嗅虏,春花似錦洛姑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至龄广,卻和暖如春硫眯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背择同。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工两入, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人敲才。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓谆刨,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親归斤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

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

  • 原文:http://www.myexception.cn/operating-system/2052286.htm...
    KYM1988閱讀 1,944評(píng)論 2 2
  • 本文主要以藍(lán)牙4.0做介紹,因?yàn)楝F(xiàn)在iOS能用的藍(lán)牙也就是只僅僅4.0的設(shè)備 用的庫(kù)就是core bluetoot...
    暮雨飛煙閱讀 840評(píng)論 0 2
  • 首先進(jìn)一則廣告: 藍(lán)牙技術(shù)聯(lián)盟(Bluetooth SIG)2010年7月7日宣布刁岸,正式采納藍(lán)牙4.0核心規(guī)范(B...
    L澤閱讀 1,445評(píng)論 3 4
  • 藍(lán)牙簡(jiǎn)介 藍(lán)牙( Bluetooth? ):是一種無線技術(shù)標(biāo)準(zhǔn)脏里,可實(shí)現(xiàn)固定設(shè)備、移動(dòng)設(shè)備和樓宇個(gè)人域網(wǎng)之間的短距離...
    Chefil閱讀 2,041評(píng)論 2 19
  • 在寫這個(gè)博客之前虹曙,空余時(shí)間抽看了近一個(gè)月的文檔和Demo迫横,系統(tǒng)給的解釋很詳細(xì),接口也比較實(shí)用酝碳,唯獨(dú)有一點(diǎn)矾踱,對(duì)于設(shè)備...
    木易林1閱讀 3,353評(píng)論 3 4