iOS開(kāi)發(fā)藍(lán)牙4.0初識(shí)
轉(zhuǎn)載 2015-09-20 15:26:44
標(biāo)簽:ios開(kāi)發(fā)藍(lán)牙ios開(kāi)發(fā)藍(lán)牙4.0ios開(kāi)發(fā)藍(lán)牙連接ios開(kāi)發(fā)藍(lán)牙掃描ios藍(lán)牙4.0
防丟自拍器
車載儀表盤
針灸儀設(shè)備
ANCS實(shí)現(xiàn)的監(jiān)控來(lái)電钳垮,短信字管,郵箱
第一張圖片防丟自拍器已經(jīng)上傳到APPSTORE,源碼已經(jīng)上傳到QQ群共享460325065
要了解一項(xiàng)技術(shù)两波,最好先了解一下歷史怀挠。1994年,愛(ài)立信一位工程師,為了解除日益增多的連接線纜的煩惱善镰,發(fā)明了一種名為藍(lán)牙的短距離無(wú)線通信技術(shù)。自2001年發(fā)布藍(lán)牙1.1版本技術(shù)規(guī)范年枕,一群諾基亞的工程師就開(kāi)始暢想炫欺,在若干年后,如何讓智能移動(dòng)設(shè)備與周邊的嵌入式設(shè)備連接的時(shí)間更長(zhǎng)熏兄,從而使得智能移動(dòng)設(shè)備成為與周邊10m范圍內(nèi)各種電子產(chǎn)品通信的中樞品洛。經(jīng)過(guò)10年的努力,藍(lán)牙技術(shù)聯(lián)盟終于在2011年發(fā)布了里程碑版本的藍(lán)牙4.0技術(shù)規(guī)范摩桶,其中最具吸引力的就是低功耗藍(lán)牙技術(shù)規(guī)范桥状。
在無(wú)線技術(shù)迅猛發(fā)展的今天 ,藍(lán)牙技術(shù)到底是一個(gè)什么位置硝清,可以通過(guò)下圖做一個(gè)簡(jiǎn)單的了解辅斟。
該圖片摘自《BLE權(quán)威教程》,我新建了一個(gè)QQ群460325065,群共享上傳了該文獻(xiàn)
?目前市場(chǎng)上影響力最大的三種無(wú)線技術(shù)芦拿,藍(lán)牙士飒,WIFI和Zigbee查邢。從上圖可以看出,藍(lán)牙的傳輸距離是最短的酵幕,功耗是高于Zigbee扰藕,低于WIFI。傳輸距離最短芳撒,只有2-10米邓深,當(dāng)然這是傳統(tǒng)藍(lán)牙,傳輸速度能達(dá)到3Mbps笔刹。如果用過(guò)諾基亞手機(jī)的人芥备,應(yīng)該知道,在那個(gè)沒(méi)有智能手機(jī)的時(shí)代徘熔,已經(jīng)有了藍(lán)牙技術(shù)门躯,而且還能用藍(lán)牙在兩個(gè)手機(jī)之間傳輸音樂(lè)和圖片。如果細(xì)心的人應(yīng)該會(huì)發(fā)現(xiàn)酷师,如今的智能手機(jī)讶凉,比如兩臺(tái)iPhone之間,在設(shè)置中山孔,是無(wú)法搜索到對(duì)方懂讯。這是為什么呢?簡(jiǎn)單的說(shuō)台颠,因?yàn)樗{(lán)牙4.0技術(shù)褐望。
什么是藍(lán)牙 4.0 ?
該圖片摘自《BLE權(quán)威教程》串前,我新建了一個(gè)QQ群460325065,群共享上傳了該文獻(xiàn)
?從上圖我們可以發(fā)現(xiàn)瘫里,全新的藍(lán)牙4.0技術(shù)并不是一種技術(shù),而是由傳統(tǒng)藍(lán)牙荡碾,高速藍(lán)牙和低功耗藍(lán)牙合而為一谨读。并且這三種藍(lán)牙可以組合使用,也可以單獨(dú)使用坛吁。其中劳殖,低功耗藍(lán)牙即BLE是藍(lán)牙4.0的核心規(guī)范。毫不夸張的說(shuō)拨脉,藍(lán)牙4.0為什么可以成為改變生活的原因哆姻,就是因?yàn)锽LE,低功耗藍(lán)牙的產(chǎn)生玫膀。因?yàn)橐磺兄悄茉O(shè)備矛缨,都需要電,電量用完,設(shè)備就是一堆廢鐵劳景。然而誉简,低功耗是硬件上的事情,跟我們手機(jī)APP有什么關(guān)系盟广,APP根本就不關(guān)心你耗電不耗電,我只寫(xiě)我的客戶端就好了啊瓮钥。實(shí)際上筋量,與APP還是有關(guān)系的,正是因?yàn)橛蠦LE和傳統(tǒng)藍(lán)牙碉熄,市場(chǎng)上是有三類藍(lán)牙產(chǎn)品的桨武。如果你不知道你在為哪一類產(chǎn)品開(kāi)發(fā)程序,你會(huì)遇到很多麻煩锈津,比如說(shuō)呀酸,老板要你用BLE傳輸音頻數(shù)據(jù),如果你不知道傳音頻是傳統(tǒng)藍(lán)牙的功能琼梆,你可能會(huì)白辛苦很久而達(dá)不到效果性誉。在舉個(gè)例子,如果老板要你監(jiān)控來(lái)電短信或者郵件等其他信息茎杂,然后通過(guò)APP發(fā)送到藍(lán)牙設(shè)備错览。如果你不知道這是ANCS的工作,而自己傻傻的去找檢測(cè)來(lái)電短信的辦法煌往,然后還要在程序退到后臺(tái)依然能起作用倾哺,并通過(guò)BLE發(fā)送到設(shè)備,那可能你的工作中會(huì)充滿煩惱刽脖。到最后還認(rèn)為你的水平很low羞海。
所以,作為iOS工程師曲管,第一件事情却邓,就是要區(qū)分你正在開(kāi)發(fā)的APP是為單模藍(lán)牙,還是雙模藍(lán)牙翘地;僅傳統(tǒng)藍(lán)牙是不需要APP的申尤,譬如市面上大多數(shù)的藍(lán)牙音箱,只要連上電腦或者手機(jī)衙耕,在電腦或者手機(jī)設(shè)備上播放音樂(lè)昧穿,系統(tǒng)底層就可以通過(guò)傳統(tǒng)藍(lán)牙協(xié)議,將音頻數(shù)據(jù)傳到藍(lán)牙音箱上播放橙喘。換句話說(shuō)时鸵,就是傳統(tǒng)藍(lán)牙部分在APP上不可控,在iOS上,更是連判斷在設(shè)置中是否連接了傳統(tǒng)藍(lán)牙都辦不到饰潜,iOS可控的部分只有BLE初坠。那為什么還要區(qū)分單模,雙模呢彭雾,知道又如何碟刺,傳統(tǒng)藍(lán)牙部分都無(wú)法控制,原因在哪薯酝?答案在于這里說(shuō)的不可控半沽,是指在iOS上,但是在硬件上是可以知道的吴菠。我們可以通過(guò)BLE將傳統(tǒng)藍(lán)牙的連接狀態(tài)者填,以及一些其他信息指定一套協(xié)議進(jìn)行溝通。當(dāng)然做葵,如果你想要實(shí)現(xiàn)像蘋(píng)果手表那樣的功能占哟,在手機(jī)上有來(lái)電和短信,或者其他軟件信息提醒的時(shí)候酿矢,在你的藍(lán)牙設(shè)備上也能接收到榨乎。那這個(gè)功能的實(shí)現(xiàn)需要用到ANCS(Apple Notification Center Service)。ANCS在可以看成一個(gè)超級(jí)權(quán)限棠涮,但卻跟傳統(tǒng)藍(lán)牙工作在不同局域谬哀,一個(gè)是通知,一個(gè)是音頻严肪。具體的實(shí)現(xiàn)史煎,我們都不得而知,這部分屬于蘋(píng)果系統(tǒng)的功能了驳糯。從我上上個(gè)月開(kāi)發(fā)過(guò)的那個(gè)ANCS產(chǎn)品來(lái)看篇梭,我個(gè)人的感覺(jué)ANCS目前存在一些BUG,ANCS的產(chǎn)品在BLE操作中酝枢,會(huì)出現(xiàn)斷開(kāi)不了的情況恬偷,所以從這點(diǎn)上看,感覺(jué)ANCS是有一些BLE的成分帘睦。而從這個(gè)協(xié)議單純的理解袍患,應(yīng)該要像傳統(tǒng)藍(lán)牙一樣,一個(gè)單獨(dú)連接竣付,與BLE無(wú)關(guān)才對(duì)诡延;但是ANCS沒(méi)有像傳統(tǒng)藍(lán)牙一樣在設(shè)置中有一個(gè)專欄;所以古胆,感覺(jué)從目前來(lái)說(shuō)肆良,貌似有BUG筛璧,也許目前已經(jīng)解決,只是我不知道惹恃。
從上圖夭谤,我們還應(yīng)該知道的是,并不是所有手機(jī)都支持藍(lán)牙4.0技術(shù)巫糙,iPhone需要4S以上的手機(jī)朗儒,安卓需要系統(tǒng)4.3及以上的版本。
到這里参淹,大家應(yīng)該對(duì)市面上的藍(lán)牙設(shè)備有一個(gè)大概的分類了采蚀,那如何區(qū)分,也說(shuō)了 承二,在iOS上區(qū)分一個(gè)設(shè)備是否包含傳統(tǒng)藍(lán)牙的?方法是通過(guò)查看設(shè)置中是否有傳統(tǒng)藍(lán)牙的連接。因?yàn)樘O(píng)果系統(tǒng)對(duì)用戶隱私的保護(hù)纲爸,傳統(tǒng)藍(lán)牙的連接亥鸠,在第一次連接時(shí),用戶必須自己手動(dòng)點(diǎn)擊連接识啦。后面可以通過(guò)設(shè)備在手機(jī)打開(kāi)藍(lán)牙時(shí)自動(dòng)連接负蚊。ANCS會(huì)在啟動(dòng)時(shí),在程序中有提示颓哮,而且這個(gè)提示框是無(wú)法去掉的家妆。而在BLE中,有時(shí)候也會(huì)出現(xiàn)提示框冕茅,而這個(gè)提示框伤极,可以在硬件上去掉。判斷BLE的方法姨伤,就是第三方APP與藍(lán)牙設(shè)備通信哨坪,就一定是BLE的功能了。據(jù)硬件工程師的說(shuō)法乍楚,ANCS是涵蓋BLE和傳統(tǒng)藍(lán)牙功能的当编。而我在測(cè)試的過(guò)程中,ANCS會(huì)在手機(jī)上彈出連接的窗口徒溪,而一旦連上忿偷,BLE的連接會(huì)受到ANCS的影響。但是在BLE斷開(kāi)的情況下臊泌,ANCS依然可用鲤桥。由于沒(méi)辦法看到ANCS是否正常,所以也不好下結(jié)論缺虐,所以我說(shuō)芜壁,也許存在BUG,所以這篇博客的名字叫藍(lán)牙4.0初識(shí)。
一般來(lái)說(shuō)慧妄,從一個(gè)技術(shù)博客的角度出發(fā)顷牌,寫(xiě)一篇博客的話,應(yīng)該是大多數(shù)的代碼塞淹,而這篇我寫(xiě)這么多不是代碼的東西窟蓝,實(shí)際上,在真正的藍(lán)牙開(kāi)發(fā)過(guò)程中饱普,如果不了解這些运挫,會(huì)產(chǎn)生很多疑惑,因?yàn)樘赘瑥膇OS藍(lán)牙開(kāi)發(fā)角度說(shuō)谁帕,蘋(píng)果已經(jīng)幫我們把底層都封裝起來(lái)了,我們只是簡(jiǎn)單的調(diào)用冯袍,毫不夸張的說(shuō)匈挖,一個(gè)半年的新手都能在兩天之內(nèi)上手,一個(gè)星期內(nèi)使用康愤。然而儡循,并不是說(shuō)你能用就能解釋清楚其中的很多狀況。從我個(gè)人來(lái)說(shuō)征冷,我是喜歡弄明白一個(gè)現(xiàn)象深處的東西择膝。而弄清楚最好的辦法,就是深入了解藍(lán)牙4.0的方方面面检激。
在了解藍(lán)牙的歷史肴捉,什么是藍(lán)牙4.0,藍(lán)牙產(chǎn)品的分類呵扛,各類產(chǎn)品能實(shí)現(xiàn)什么功能每庆,以及如何為你的需求做藍(lán)牙技術(shù)上的選擇之后,下面討論的是藍(lán)牙連接的問(wèn)題今穿。
藍(lán)牙4.0連接?中的一些小知識(shí)
說(shuō)到連接缤灵,不得不重提之前兩臺(tái)iPhone手機(jī)在設(shè)置中無(wú)法發(fā)現(xiàn)發(fā)現(xiàn)對(duì)方的問(wèn)題,兩臺(tái)設(shè)備蓝晒,要相互知道對(duì)方腮出,唯一的辦法,只能是至少有一個(gè)人告訴對(duì)方芝薇,我是誰(shuí)胚嘲。如果兩臺(tái)設(shè)備都不說(shuō)話,那肯定不知道對(duì)方是藍(lán)牙設(shè)備的身份洛二。所以馋劈,藍(lán)牙連接的過(guò)程攻锰,實(shí)際上就是一個(gè)溝通的過(guò)程,在藍(lán)牙設(shè)備中妓雾,說(shuō)話是通過(guò)廣播一段無(wú)線信號(hào)實(shí)現(xiàn)娶吞,一臺(tái)藍(lán)牙設(shè)備是不能同時(shí)廣播和接收廣播,因?yàn)槟壳靶酒€沒(méi)那么強(qiáng)大械姻。在藍(lán)牙通信中妒蛇,接收廣播的那個(gè)設(shè)備叫主機(jī)(Central),發(fā)送廣播的設(shè)備叫從機(jī)(Peripheral)楷拳。而通常手機(jī)都處在主機(jī)狀態(tài)绣夺,也就是只能接收廣播,而自己沒(méi)有向周圍發(fā)送廣播欢揖。所以兩臺(tái)手機(jī)之間一般是無(wú)法發(fā)現(xiàn)對(duì)方的陶耍。除非,你寫(xiě)一段程序她混,讓手機(jī)向周圍發(fā)送廣播物臂。目前,作為主機(jī)的設(shè)備产上,是可以與多個(gè)從機(jī)進(jìn)行連接的,而作為從機(jī)的設(shè)備蛾狗,通常只能與一個(gè)主機(jī)進(jìn)行連接晋涣,通常在與一個(gè)主機(jī)相連后,設(shè)備就會(huì)關(guān)閉廣播沉桌。所以谢鹊,在開(kāi)發(fā)過(guò)程中操骡,可能你的身邊有多個(gè)藍(lán)牙設(shè)備處于運(yùn)行狀態(tài)纵寝,但是一個(gè)也搜索不到扁达,那就是因?yàn)閯e人的手機(jī)已經(jīng)連接了其徙。然而拖云,在藍(lán)牙設(shè)備上矩欠,并不是在連接之后就必須關(guān)閉廣播倦踢,是可以在芯片上實(shí)現(xiàn)讓他繼續(xù)廣播的炕倘。那是不是就能說(shuō)明一臺(tái)從機(jī)就可以連接多臺(tái)主機(jī)呢?目前答案是不行求冷。因?yàn)槟壳笆袌?chǎng)上瘤运,影響最大的是美國(guó)TI公司的CC2540/CC2541,以及新出來(lái)的CC2640/CC2650系列產(chǎn)品匠题,目前沒(méi)有實(shí)現(xiàn)他作為從機(jī)時(shí)拯坟,多連的功能。從另一個(gè)角度說(shuō)韭山,主機(jī)能連接多個(gè)郁季,從機(jī)也連接多臺(tái)設(shè)備冷溃,通信協(xié)議無(wú)疑會(huì)變得很復(fù)雜,從機(jī)發(fā)數(shù)據(jù)到底發(fā)給誰(shuí)梦裂,怎么去控制他發(fā)送似枕。單這兩個(gè)問(wèn)題,就決定了藍(lán)牙設(shè)備作為從機(jī)時(shí)塞琼,只能連接一個(gè)主機(jī)菠净。作為主機(jī)的設(shè)備,采用藍(lán)牙4.0協(xié)議的話彪杉,也不是連接任意臺(tái)設(shè)備的毅往,經(jīng)過(guò)測(cè)試,iPhone手機(jī)最多能連10臺(tái)從機(jī)派近,安卓手機(jī)得看手機(jī)性能攀唯,6到10臺(tái)不等。如果要連接更多的設(shè)備渴丸,在藍(lán)牙4.1侯嘀;4.2中,藍(lán)牙聯(lián)盟已經(jīng)在改進(jìn)藍(lán)牙協(xié)議了谱轨。那實(shí)現(xiàn)這一點(diǎn)戒幔,就需要你的手機(jī)和你的藍(lán)牙設(shè)備里的芯片都支持到藍(lán)牙4.1,4.2土童,那無(wú)疑對(duì)手機(jī)的要求更高诗茎,用戶群更小,而市場(chǎng)上支持4.1和4.1藍(lán)牙協(xié)議的芯片并不多献汗,即使有也在試驗(yàn)階段敢订,不一定穩(wěn)定。而10個(gè)的連接數(shù)罢吃,已經(jīng)能滿足大多數(shù)用戶的需求了楚午,新的芯片成本肯定更高,所以在選擇支持4.1或4.2協(xié)議時(shí)尿招,慎重矾柜。(小秘密:在做安卓測(cè)試的時(shí)候,在京東上買了多臺(tái)手機(jī)就谜,然后7天無(wú)理由退貨把沼,又退回去,自己只需要一些快遞費(fèi))
該圖片摘自《藍(lán)牙4.0 BLE開(kāi)發(fā)完全手冊(cè) 物聯(lián)網(wǎng)開(kāi)發(fā)技術(shù)實(shí)戰(zhàn)》吁伺,我新建了一個(gè)QQ群460325065,群共享上傳了該文獻(xiàn)
如果做過(guò)藍(lán)牙開(kāi)發(fā)的人應(yīng)該都知道饮睬,連接藍(lán)牙并不是百分百成功的,很可能你連上之后秒斷篮奄,仿佛沒(méi)有連接一樣捆愁。并不是程序?qū)懙挠袉?wèn)題割去,APP上確實(shí)會(huì)發(fā)生這樣的事情。根本原因在于底層藍(lán)牙協(xié)議昼丑。
?上圖就是藍(lán)牙4.0BLE協(xié)議棧呻逆,對(duì)于iOS開(kāi)發(fā)人員來(lái)說(shuō),你也可以完全不用管它菩帝,但是做過(guò)安卓的同學(xué)肯定知道GATT服務(wù)器咖城。它位于整個(gè)協(xié)議棧的最高層,與APP進(jìn)行交互呼奢。在安卓開(kāi)發(fā)過(guò)程中宜雀,代碼可以明確的知道APP上的BLE連接是委托GATT服務(wù)器完成的。而在iOS上握础,就是藍(lán)牙管理中心CBCentralManager辐董。蘋(píng)果已經(jīng)把底層都封裝起來(lái)了,這可以說(shuō)是做iOS的幸福之處禀综,也可以說(shuō)是對(duì)開(kāi)發(fā)者的不幸之處简烘,因?yàn)橥耆磺宄槭裁磿?huì)這樣。
GATT服務(wù)器才是真正決定連接是否成功的關(guān)鍵定枷。GATT在收到連接請(qǐng)求后孤澎,會(huì)像下繼續(xù)請(qǐng)求資源,而由于藍(lán)牙資源是有限的欠窒,所以并不是每一次請(qǐng)求都會(huì)成功亥至,特別當(dāng)你實(shí)現(xiàn)多連的時(shí)候,連接的越多贱迟,越容易出現(xiàn)連接斷開(kāi)的情況。
還有一個(gè)原因絮供,兩個(gè)設(shè)備之間是如何確定對(duì)方還處于連接狀態(tài)的呢衣吠,也是類似于一個(gè)心跳包的概念。上圖中的“有效連接間隔”壤靶。
☆短間隔的連接事件:兩設(shè)備都會(huì)以高能耗運(yùn)行缚俏,高數(shù)據(jù)吞吐量,發(fā)送等到時(shí)間短
☆長(zhǎng)間隔的連接事件:兩設(shè)備都會(huì)以低能耗運(yùn)行贮乳,低數(shù)據(jù)吞吐量忧换,發(fā)送等待時(shí)間長(zhǎng)
如果連接過(guò)程經(jīng)常斷開(kāi),可以嘗試將硬件的連接時(shí)間間隔?縮短向拆。當(dāng)然有利有弊亚茬。
?那對(duì)于這個(gè)問(wèn)題,在軟件怎么解決浓恳?實(shí)際上沒(méi)法從根本上解決刹缝,只能多連幾次碗暗,可以在藍(lán)牙4.0斷開(kāi)時(shí)自動(dòng)重連。
藍(lán)牙的東西太多梢夯,一篇文章肯定講不清楚言疗。篇幅過(guò)長(zhǎng)會(huì)看的疲勞,下面講一下CODING颂砸。
?第二部分:XCODE中的操作
一.一個(gè)簡(jiǎn)單的demo搭建?
1.用xcode建立一個(gè)project噪奄,建一個(gè)Single View Application?,給項(xiàng)目取個(gè)名字BleTest,我選的語(yǔ)言是OC人乓。
2.?在ViewController.h頭文件中加入#import "CoreBluetooth/CoreBluetooth.h"這個(gè)頭文件勤篮,兩個(gè)委托方法<</span>CBCentralManagerDelegate,CBPeripheralDelegate>,聲明一個(gè)變量@property (strong,nonatomic) CBCentralManager * MyCentralManager;
3.?在ViewController.m的viewDidLoad方法中加入self.MyCentralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];?
4.在ViewController.m方法體中加入如下兩個(gè)方法
pragma mark - Navigation
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
switch (central.state) {
case CBCentralManagerStateUnknown:
break;
case CBCentralManagerStateUnsupported:
NSLog(@"模擬器不支持藍(lán)牙調(diào)試");
break;
case CBCentralManagerStateUnauthorized:
break;
case CBCentralManagerStatePoweredOff:
NSLog(@"藍(lán)牙處于關(guān)閉狀態(tài)");
break;
case CBCentralManagerStateResetting:
break;
case CBCentralManagerStatePoweredOn:
? NSLog(@"藍(lán)牙已開(kāi)啟");
[self.MyCentralManager scanForPeripheralsWithServices:nil options:nil];?
break;
}
}
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
NSLog(@"能發(fā)現(xiàn)設(shè)備:%@",peripheral.name);
}
?5.運(yùn)行程序撒蟀,一個(gè)最簡(jiǎn)單的藍(lán)牙程序就完成了
如何手機(jī)設(shè)備的藍(lán)牙已打開(kāi)叙谨,在LOG消息中可以看到附近的藍(lán)牙設(shè)備。藍(lán)牙不支持模擬器調(diào)試保屯,必須使用iPhone4S以上的真機(jī)調(diào)試手负。
二.實(shí)現(xiàn)更多功能?
1.?CBCentralManager主設(shè)管理中心,需要且必須是單例姑尺。一個(gè)程序中只能有一處竟终,如果有兩處,并不能同時(shí)在兩處連接切蟋。我曾試過(guò)统捶,最多只能在兩處掃描到設(shè)備。道理很簡(jiǎn)單柄粹,在手機(jī)上喘鸟,藍(lán)牙就跟相機(jī)一樣都只有一個(gè),能同時(shí)實(shí)現(xiàn)兩個(gè)攝像頭拍照嗎驻右,不能什黑。如何解決,只能在程序中繼承堪夭,傳遞主設(shè)對(duì)象或建一個(gè)全局變量愕把。self.MyCentralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];對(duì)于這個(gè)方法,第一個(gè)參數(shù)沒(méi)得說(shuō)森爽,你非要賦值為nil也可以的恨豁,再用self.MyCentralManager.delegate=self;也可以實(shí)現(xiàn)。第二個(gè)參數(shù)爬迟,If the value is nil, the central manager dispatches central role events using the main queue.如果設(shè)置為nil橘蜜,默認(rèn)在主線程中跑。
2.?CBCentralManagerDelegate委托方法付呕,必須要實(shí)現(xiàn)的一個(gè)方法扮匠,- (void)centralManagerDidUpdateState:(CBCentralManager *)central用于檢測(cè)當(dāng)前設(shè)備的藍(lán)牙狀態(tài)捧请。而我通常喜歡在CBCentralManagerStatePoweredOn藍(lán)牙開(kāi)啟時(shí)才開(kāi)始掃描。
3.掃描的方法是[self.MyCentralManager scanForPeripheralsWithServices:nil options:nil];?這里兩個(gè)參數(shù)都是nil棒搜,也可以不用nil疹蛉,那這兩個(gè)參數(shù)是什么意思呢?第一個(gè)參數(shù)是指力麸,掃描指定的服務(wù)(Services)可款。第二個(gè)參數(shù)是掃描過(guò)程中的一些設(shè)置。服務(wù)是什么克蚂?打個(gè)比方闺鲸,如果你需要到銀行取錢,第一步埃叭,你需要找到銀行的網(wǎng)點(diǎn)摸恍,第二步,找一個(gè)柜臺(tái)的服務(wù)員赤屋。找到網(wǎng)點(diǎn)并不能進(jìn)行存錢取錢操作立镶,但是必須找到網(wǎng)點(diǎn),才能找到服務(wù)員类早,而存錢取錢操作必須在網(wǎng)點(diǎn)內(nèi)進(jìn)行才被允許媚媒。對(duì)應(yīng)到藍(lán)牙上,服務(wù)員就是特性(characteristic)涩僻,如果要進(jìn)行數(shù)據(jù)的交互缭召,只能對(duì)特性進(jìn)行。一個(gè)藍(lán)牙設(shè)備逆日,可能有多個(gè)服務(wù)嵌巷,如果你只需要掃描指定的服務(wù),就可以指定第一個(gè)參數(shù)室抽。第二個(gè)參數(shù)搪哪,可以有很多其他設(shè)置。
停止掃描的方法[self.MyCentralManager stopScan];這個(gè)方法狠半,通常會(huì)在重新搜索附近藍(lán)牙設(shè)備的時(shí)候用到。
實(shí)現(xiàn)重新掃描?颤难,將委托再指定一次神年。停止掃描,同時(shí)移除數(shù)組中所有到的掃描行嗤,再開(kāi)啟掃描已日。通常,在掃描到某一個(gè)設(shè)備后栅屏,都加入到一個(gè)數(shù)組中飘千,以便進(jìn)行連接堂鲜。
-(void)seachAction{
// NSLog(@“重新搜索");
self.cbCentralMgr.delegate=self;
[self.cbCentralMgr stopScan];
if (dataArray.count) {
[dataArray removeAllObjects];
}
NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO],CBCentralManagerScanOptionAllowDuplicatesKey, nil];
[self.cbCentralMgr scanForPeripheralsWithServices:nil options:dic];
}
4.掃描中的設(shè)置參數(shù):如果第二個(gè)參數(shù)為nil,掃描到設(shè)備的次數(shù)一般為兩次护奈,就是- (void)centralManager: didDiscoverPeripheral: advertisementData: RSSI:執(zhí)行的次數(shù)為兩次缔莲。而對(duì)于一些特殊的APP,如藍(lán)牙稱或者通過(guò)廣播辨別設(shè)備狀態(tài)時(shí)霉旗,需要實(shí)時(shí)接收廣播數(shù)據(jù)痴奏。那可以用CBCentralManagerScanOptionAllowDuplicatesKey,代碼為:
NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],CBCentralManagerScanOptionAllowDuplicatesKey, nil];
[self.MyCentralManager scanForPeripheralsWithServices:nil options:dic];
CBCentralManagerScanOptionSolicitedServiceUUIDsKey
An array (an instance of NSArray) of service UUIDs (represented by CBUUID objects) that you want to scan for.Specifying this scan option causes the central manager to also scan for peripherals soliciting any of the services contained in the array.這是蘋(píng)果的說(shuō)明厌秒,簡(jiǎn)單說(shuō)就是給一個(gè)數(shù)組读拆,然后掃描指定數(shù)組中的服務(wù),這個(gè)方法跟scanForPeripheralsWithServices的第一個(gè)參數(shù)一樣的功能鸵闪。而掃描只有CBCentralManagerScanOptionAllowDuplicatesKey和CBCentralManagerScanOptionSolicitedServiceUUIDsKey兩個(gè)參數(shù)可以選擇檐晕。比較有用的是第一個(gè)。
5.連接的方法 [self.MyCentralManager connectPeripheral:peripheral options:nil];如果連接成功建立蚌讼,則會(huì)調(diào)用centralManager:didConnectPeripheral:回調(diào)方法辟灰,如果連接建立失敗,則調(diào)用 centralManager:didFailToConnectPeripheral:error:方法啦逆。這個(gè)連接的方法會(huì)一直執(zhí)行伞矩。如何實(shí)現(xiàn)自動(dòng)斷線重連,就是在斷開(kāi)的委托方法中夏志,執(zhí)行連接藍(lán)牙的方法乃坤。由于藍(lán)牙的有效距離在10米,當(dāng)手機(jī)離開(kāi)藍(lán)牙設(shè)備10米范圍之后沟蔑,手機(jī)可能會(huì)失去連接湿诊,而有些情況下,需要手機(jī)在回到10范圍內(nèi)的時(shí)候自動(dòng)連接瘦材。那我們只需要在斷開(kāi)連接的時(shí)候厅须,執(zhí)行連接操作,因?yàn)樗{(lán)牙會(huì)一直處于嘗試連接指定藍(lán)牙的操作食棕,沒(méi)有時(shí)間限制朗和。但如果當(dāng)藍(lán)牙對(duì)象被釋放后,潛在的藍(lán)牙連接嘗試操作也會(huì)被取消掉簿晓。第一個(gè)參數(shù)眶拉,連接的藍(lán)牙對(duì)象,沒(méi)什么說(shuō)的憔儿;第二個(gè)參數(shù)忆植,可以有三種:CBConnectPeripheralOptionNotifyOnConnectionKey,CBConnectPeripheralOptionNotifyOnDisconnectionKey和CBConnectPeripheralOptionNotifyOnNotificationKey這三種參數(shù)的用處在于沒(méi)有使用background mode?的時(shí)候是否顯示Alert提醒信息,三種參數(shù)如果不做任何設(shè)置朝刊,都默認(rèn)為NO耀里,第一種參數(shù)OnConnectionKey在程序被掛起時(shí),連接成功顯示Alert提醒框拾氓,第二種參數(shù)冯挎,OnDisconnectionKey在程序被掛起時(shí),斷開(kāi)連接顯示Alert提醒框痪枫,第三種參數(shù)织堂,OnNotificationKey在程序被掛起時(shí),顯示所有的提醒消息奶陈。
斷開(kāi)連接的方法[self.MyCentralManager? cancelPeripheralConnection:peripheral];這個(gè)方法會(huì)取消已經(jīng)連接成功的藍(lán)牙易阳,也會(huì)取消正在連接中的藍(lán)牙。這個(gè)方法并不是使用的塊方法吃粒,當(dāng)執(zhí)行斷開(kāi)連接之后繼續(xù)對(duì)這個(gè)藍(lán)牙對(duì)象進(jìn)行操作指令潦俺,這個(gè)操作指令也許能完成,也許不能徐勃。因?yàn)楹苡锌赡芷渌鸻pp可能仍然保持著對(duì)這個(gè)藍(lán)牙的連接事示,斷開(kāi)本地的藍(lán)牙連接并不能保證潛在的物理連接會(huì)立刻斷開(kāi),但是從app的角度看僻肖,會(huì)認(rèn)為藍(lán)牙是立刻斷開(kāi)了的肖爵,而且藍(lán)牙主設(shè)管理中心也會(huì)立刻執(zhí)行這個(gè)委托方法centralManager:didDisconnectPeripheral:error:。所以在理論上臀脏,iOS設(shè)備是可以同時(shí)連接10個(gè)藍(lán)牙設(shè)備的劝堪,但是當(dāng)之前的連接斷開(kāi)之后,并不能在物理層保證藍(lán)牙已經(jīng)斷開(kāi)連接揉稚,所以有時(shí)候會(huì)發(fā)生秒啦,連接數(shù)還沒(méi)達(dá)到10個(gè),藍(lán)牙就死掉的情況搀玖。?
6.?- retrieveConnectedPeripheralsWithServices:根據(jù)制定的服務(wù)余境,找到當(dāng)前系統(tǒng)處于連接狀態(tài)的藍(lán)牙中包含這個(gè)服務(wù)的所有藍(lán)牙對(duì)象。- retrievePeripheralsWithIdentifiers:根據(jù)UUID找到所有匹配的藍(lán)牙對(duì)象灌诅。
7.發(fā)送數(shù)據(jù)?- (void)writeValue:(NSData *)data forCharacteristic:(CBCharacteristic *)characteristic type:(CBCharacteristicWriteType)type;通常我會(huì)使用下面的寫(xiě)法芳来,遍歷整個(gè)服務(wù),找到通信需要的特性猜拾,當(dāng)然即舌,如果做過(guò)多種藍(lán)牙的同學(xué)應(yīng)該會(huì)知道,這個(gè)函數(shù)的最后一個(gè)參數(shù)关带,可能有兩種侥涵,如果你的程序出現(xiàn)連接正常,而你確定執(zhí)行了寫(xiě)數(shù)據(jù)的函數(shù)宋雏,但是硬件確實(shí)沒(méi)有反應(yīng)芜飘,那很有可能是你的CBCharacteristicWriteType不對(duì),需要使用另一種磨总,一共是兩種CBCharacteristicWriteWithResponse和CBCharacteristicWriteWithoutResponse嗦明,一般寫(xiě)IC程序的開(kāi)發(fā)人員都是使用一個(gè)叫LightBlue的APP,用這個(gè)APP可以看到藍(lán)牙設(shè)備的服務(wù)蚪燕,特性娶牌,以及讀寫(xiě)類型。
for (CBCharacteristic *characteristic in [[peripheral.services objectAtIndex:i] characteristics])?
{ if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:UUID_FFF6]])
{ [self.peripheralOpration writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];
}
}?
而如果主設(shè)備要接收來(lái)自從機(jī)的數(shù)據(jù)的話馆纳,需要給從機(jī)一個(gè)權(quán)限诗良,而且還要指定特性?,[peripheral setNotifyValue:YES forCharacteristic:characteristic];這樣的話鲁驶,從機(jī)就可以通過(guò)參數(shù)中的characteristic特性傳數(shù)據(jù)到主機(jī)鉴裹,而主機(jī)響應(yīng)的方式是通過(guò)-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error這個(gè)委托方法。
8钥弯,多個(gè)藍(lán)牙對(duì)象時(shí)径荔,如何管理,可以將藍(lán)牙對(duì)象看成簡(jiǎn)單的字典對(duì)象脆霎。在要求與多個(gè)藍(lán)牙設(shè)備同時(shí)通信時(shí)总处,逐個(gè)進(jìn)行操作。有時(shí)候會(huì)產(chǎn)生分組的概念睛蛛,而區(qū)分出每個(gè)藍(lán)牙對(duì)象不同的方法就是藍(lán)牙設(shè)備的UUID鹦马,UUID在每個(gè)手機(jī)設(shè)備上?生成的都不一樣,不同的藍(lán)牙設(shè)備玖院,在同一臺(tái)手機(jī)上也不一樣菠红。因?yàn)閁UID是由唯一的MAC地址和手機(jī)的識(shí)別碼一起通過(guò)一個(gè)加密算法得到。目前市場(chǎng)上难菌,出貨比較大的是藍(lán)牙燈试溯,很多藍(lán)牙燈均有房間,和分組的概念郊酒,所以這一點(diǎn)也比較有用遇绞。
9.如何實(shí)時(shí)獲取RRSI值,當(dāng)未連接的時(shí)候燎窘,可以設(shè)置一直接收廣播信息摹闽,方法看上面第3個(gè)知識(shí)點(diǎn),在- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI的最后一個(gè)參數(shù)中就是RRSI值褐健。如果對(duì)于已連接的設(shè)備付鹿,也需要實(shí)時(shí)檢測(cè)RRSI值澜汤,例如目前市場(chǎng)上大多數(shù)的藍(lán)牙防丟器或其他藍(lán)牙防丟設(shè)備,現(xiàn)在只能在程序中寫(xiě)一個(gè)計(jì)時(shí)器舵匾,隔一定時(shí)間間隔俊抵,去獲取
-(void)ShowRSSI{
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
dispatch_source_set_timer(_timer,dispatch_walltime(NULL, 0),1.0*NSEC_PER_SEC, 0); //每秒執(zhí)行
dispatch_source_set_event_handler(_timer, ^{
if(timeout<=0){ //倒計(jì)時(shí)結(jié)束,關(guān)閉
dispatch_source_cancel(_timer);
dispatch_async(dispatch_get_main_queue(), ^{
//設(shè)置界面的按鈕顯示 根據(jù)自己需求設(shè)置
// NSLog(@"--");
});
}else{
dispatch_async(dispatch_get_main_queue(), ^{
if (bleConnectViewContrller.peripheralOpration.state==2) {
if (IS_IOS_8) {
[bleConnectViewContrller.peripheralOpration readRSSI];
}else{
// NSLog(@"%@",[NSString stringWithFormat:@"%@",[bleConnectViewContrller.peripheralOpration RSSI]]);
}
}else{
// NSLog(@"--");
}
});
timeout--;
}
});
dispatch_resume(_timer);
}
10.關(guān)于將iPhone作為從機(jī)坐梯,像周圍發(fā)送廣播的用法徽诲,實(shí)際上這種需求比較少,通常手機(jī)都是主機(jī)吵血,這里不做論述谎替,如有需要可以提供demo。
11.通常藍(lán)牙設(shè)備會(huì)在連接設(shè)備之后蹋辅,會(huì)去發(fā)現(xiàn)設(shè)備的服務(wù)和特性钱贯,甚至很多設(shè)備在連接成功的時(shí)候都會(huì)對(duì)設(shè)備做一個(gè)初始命令的設(shè)置,譬如藍(lán)牙燈泡在剛連上時(shí)侦另,將燈泡亮度調(diào)到最大喷舀。而有的APP會(huì)有自動(dòng)重連功能,那在程序啟動(dòng)的時(shí)候就會(huì)發(fā)生周圍多個(gè)設(shè)備淋肾,并連接硫麻,尋找服務(wù)特性,并發(fā)送數(shù)據(jù)樊卓。我想說(shuō)的是拿愧,這個(gè)時(shí)候如果程序中有重新搜索功能的話,會(huì)出現(xiàn)bug碌尔。之前講到過(guò)浇辜,藍(lán)牙連接執(zhí)行了斷開(kāi)方法后,并不能立即在物理連接上斷開(kāi)唾戚。所以通常柳洋,不要將自動(dòng)重連和重新搜索功能放在一起。
如果需要知道文章中文獻(xiàn)的叹坦,可以到QQ群460325065下載熊镣。
9月22號(hào)收到第一個(gè)質(zhì)疑,連接個(gè)數(shù)募书,我寫(xiě)的最多10個(gè)绪囱,有人說(shuō)可以超過(guò)這個(gè)數(shù),百度了一下莹捡,沒(méi)有找到直接證明可以超過(guò)10個(gè)的證據(jù)鬼吵。實(shí)際上,藍(lán)牙協(xié)議并沒(méi)有規(guī)定上限篮赢,理論上可以連接無(wú)數(shù)個(gè)齿椅。但是在手機(jī)主設(shè)端做不到琉挖,一個(gè)原因?yàn)橹髟O(shè)的藍(lán)牙資源有限;二個(gè)是因?yàn)檫B接的個(gè)數(shù)越多涣脚,手機(jī)需要跟所有設(shè)備保持連接粹排,需要逐個(gè)輪訓(xùn),發(fā)送連接存在的消息涩澡。而蘋(píng)果上也對(duì)藍(lán)牙發(fā)送時(shí)間間隔做了一個(gè)設(shè)定。所以目前來(lái)說(shuō)坠敷,連接個(gè)數(shù)終有上限妙同。超過(guò)10個(gè)的限制也是時(shí)間問(wèn)題,但是具體一臺(tái)手機(jī)能連多少個(gè)從機(jī)膝迎,就需要針對(duì)自己的產(chǎn)品做詳細(xì)測(cè)試了粥帚。也許有其他非TI廠家生產(chǎn)的芯片,可以做到超過(guò)10個(gè)限次。
有朋友說(shuō)運(yùn)行程序沒(méi)有任何反應(yīng)芒涡,是因?yàn)楦浇揪蜎](méi)有藍(lán)牙設(shè)備,如果沒(méi)有藍(lán)牙設(shè)備卖漫,也可以通過(guò)兩臺(tái)iPhone或者iPad將其中一個(gè)設(shè)為從機(jī)進(jìn)行測(cè)試费尽。?
有朋友問(wèn)到iOS中HFP開(kāi)發(fā)?,通過(guò)藍(lán)牙設(shè)備實(shí)現(xiàn)打電話的功能羊始。這個(gè)功能確實(shí)能實(shí)現(xiàn)旱幼,但是跟iOS APP關(guān)系不大,完全由藍(lán)牙設(shè)備配合系統(tǒng)協(xié)議實(shí)現(xiàn)的突委。APP端只能對(duì)BLE操作柏卤,如果要錄下通話內(nèi)容,只能在開(kāi)始通話時(shí)匀油,讓藍(lán)牙設(shè)備傳一個(gè)信號(hào)到iPhone上缘缚,開(kāi)始錄音;在通話結(jié)束時(shí)敌蚜,再傳一個(gè)信號(hào)到手機(jī)桥滨,結(jié)束錄音。