iOS中的藍(lán)牙開(kāi)發(fā)以及對(duì)iOS中設(shè)計(jì)模式的進(jìn)一步理解(47,48,49,50周總結(jié))

藍(lán)牙開(kāi)發(fā)之第一次:

忙完IOMix,還在研究iOS的音頻框架,老板突然就說(shuō)要先做藍(lán)牙相關(guān)的項(xiàng)目了。于是就開(kāi)始了第一次開(kāi)發(fā)iOS藍(lán)牙應(yīng)用。兩周時(shí)間,厘清了很多之前模糊的地方。

首先有三個(gè)事情需要說(shuō)明:

1、BLE(藍(lán)牙4.0)可以實(shí)現(xiàn)1連多(我做的項(xiàng)目就是1臺(tái)手機(jī)連接8個(gè)藍(lán)牙模塊);

2、iOS這邊是拿不到藍(lán)牙模塊的mac地址的(安卓可以)(網(wǎng)上說(shuō)可以通過(guò)藍(lán)牙模塊額外的返回值傳送);

3、iOS BLE的開(kāi)發(fā),用到的官方框架是CoreBluetooth。當(dāng)然,會(huì)有人基于此封裝成其它第三方框架(基本上是將官方的“代理回調(diào)”封裝成“block回調(diào)”),此次開(kāi)發(fā)就是用了第三方的封裝框架。

框架的選擇。一開(kāi)始經(jīng)理建議我可以使用YmsCoreBluetooth,不過(guò)我看它的星星數(shù),就感覺(jué)有點(diǎn)兒不靠譜兒,后面使用,果不其然,有個(gè)坑一直跳不出去(好像是發(fā)送指令時(shí)peripheral對(duì)象一直為空,數(shù)據(jù)發(fā)不出去,當(dāng)時(shí)對(duì)藍(lán)牙的整個(gè)流程也不熟悉,所以坑沒(méi)跳出去)。所以后面又上網(wǎng)查了一下,找到BabyBluetooth(有想過(guò)用回官方框架,不過(guò)2周時(shí)間,猜想是來(lái)不及了),運(yùn)行它們demo,看起來(lái)不錯(cuò)。又按照demo自己寫(xiě)了一下,可以鏈接和發(fā)數(shù)據(jù),于是就決定用這個(gè)了。

因?yàn)橹伴_(kāi)發(fā)過(guò)Wi-Fi通訊類型的APP,所以對(duì)比著Wi-Fi來(lái)理解。一開(kāi)始,我猜想:一個(gè)“服務(wù)”,會(huì)不會(huì)就是一條指令,而“服務(wù)”下一層的若干“特征”,就是每條指令里面的對(duì)應(yīng)屬性?后來(lái)又猜想,是不是一個(gè)“特征”對(duì)應(yīng)一條指令?上面的猜想都是錯(cuò)的。那“服務(wù)”和“特征究竟是什么鬼?

現(xiàn)在手上接觸到的藍(lán)牙模塊,都只有一個(gè)“服務(wù)”(我也不知道該對(duì)應(yīng)socket(Wi-Fi)通訊里的哪部分內(nèi)容),然后“服務(wù)”里面的若干“特征”,有一個(gè)“特征”的屬性是“Data In”的,這個(gè)“特征”就是用于寫(xiě)入(發(fā)送)數(shù)據(jù)(指令)給硬件的,沒(méi)錯(cuò),就是無(wú)論你有多少條指令,都是通過(guò)這個(gè)“特征”寫(xiě)入。在我們的藍(lán)牙模塊中,要用到的“服務(wù)”的UUID(唯一標(biāo)示符)是“FF12”,寫(xiě)入數(shù)據(jù)的這個(gè)“特征”是“FF01”。

所以,你如果要寫(xiě)入(發(fā)送)數(shù)據(jù),在打包好指令(指令的定義、打包就和socket通訊的類似)后,找到peripheral對(duì)象(決定你要發(fā)給哪個(gè)藍(lán)牙模塊.在鏈接多個(gè)藍(lán)牙的時(shí)候要鑒別確定,連結(jié)單個(gè)藍(lán)牙就不需要了),找到“特征”,再利用peripheral對(duì)象調(diào)用writeValue: forCharacteristic: type:方法(或者說(shuō)發(fā)送writeValue: forCharacteristic: type:消息給peripheral對(duì)象),第1個(gè)參數(shù)傳指令內(nèi)容,第2個(gè)參數(shù)傳寫(xiě)入的“特征”對(duì)象,第3個(gè)參數(shù)傳是否有回應(yīng)。是不是很明白清晰?

所以,(寫(xiě)入)“特征”它就像一個(gè)管道、一個(gè)通道,表示可以通過(guò)它來(lái)進(jìn)行指令的寫(xiě)入,無(wú)論你有多少指令,都是利用這個(gè)“特征”發(fā)送。

硬件返回的數(shù)據(jù),就不是走這個(gè)“通道了”,它另外有一個(gè)“Data Out”的“特征”,這個(gè)“特征”專門負(fù)責(zé)數(shù)據(jù)從模塊發(fā)出(發(fā)給連結(jié)的手機(jī))。只要“監(jiān)聽(tīng)”了這個(gè)“特征”,就能收到從模塊發(fā)出的數(shù)據(jù)了。所以,和走tcp傳輸?shù)腤i-Fi不同,tcp發(fā)送和接收數(shù)據(jù),都是在同一個(gè)“通道”進(jìn)行;而藍(lán)牙,則數(shù)據(jù)發(fā)送用一個(gè)“特征”,數(shù)據(jù)接收,又用另外一個(gè)“特征”,是兩個(gè)不同的“管道”(容許我暫時(shí)這么理解)。

上面說(shuō)到用writeValue: forCharacteristic: type:方法發(fā)送指令,好像沒(méi)有用到“服務(wù)”,那“服務(wù)”還有什么用?用于發(fā)送數(shù)據(jù)時(shí)找“特征”,因?yàn)椤胺?wù)”和“特征”是樹(shù)狀結(jié)構(gòu),要找到“特征”,就必須通過(guò)“服務(wù)”。

另外,writeValue: forCharacteristic: type:的第三個(gè)參數(shù),其實(shí)只有兩種情況,一個(gè)是有返回值的CBCharacteristicWriteWithResponse,另外一個(gè)是沒(méi)有返回值的CBCharacteristicWriteWithoutResponse。這個(gè)參數(shù)可不是你想寫(xiě)哪個(gè)就寫(xiě)哪個(gè),要決定于該“特征”的屬性(CBCharacteristicProperties類型),有10種可能。CBCharacteristicPropertyWriteWithoutResponse對(duì)應(yīng)的是CBCharacteristicWriteWithoutResponse,CBCharacteristicPropertyWrite對(duì)應(yīng)的是CBCharacteristicWriteWithResponse,不能寫(xiě)錯(cuò),否則就會(huì)發(fā)不出去指令。我就之前就掉進(jìn)這個(gè)坑一次。

對(duì)iOS中“設(shè)計(jì)模式”的進(jìn)一步理解:

隨著寫(xiě)項(xiàng)目的數(shù)量提升,再回頭去看MVC,又有了深一點(diǎn)的認(rèn)識(shí)。

在項(xiàng)目實(shí)踐中,我發(fā)現(xiàn)很難嚴(yán)格遵守MVC模式,當(dāng)然我不是指大家把MVC三者搞混,而是大家都會(huì)想方設(shè)法給控制器“C”減肥,將一些其它功能獨(dú)立出控制器之外。所以無(wú)論是《iOS編程》書(shū)中提及到的MVCS,還是在網(wǎng)上大家經(jīng)常討論的MVVM,兩者的目標(biāo)應(yīng)該是一致的——給控制器“C”瘦身。

其實(shí)從經(jīng)理寫(xiě)Device類(負(fù)責(zé)實(shí)現(xiàn)和硬件通訊功能的類)開(kāi)始,項(xiàng)目就不是嚴(yán)格意義上的MVC模式了,它將“負(fù)責(zé)和硬件通訊的功能”從控制器“V”中獨(dú)立開(kāi)來(lái)。然后我又將“負(fù)責(zé)數(shù)據(jù)本地保存的功能”獨(dú)立到Store類中。再用一個(gè)單例“持有”它們,其它控制器通過(guò)這個(gè)單例獲取對(duì)應(yīng)的能力(和硬件通訊、保存數(shù)據(jù))或獲取數(shù)據(jù)。

所以我們以后和硬件通訊類型的APP,我們項(xiàng)目的組織模式可以說(shuō)是MVCDS了:D負(fù)責(zé)和硬件通訊,S負(fù)責(zé)保存數(shù)據(jù)。也正是用了這種“設(shè)計(jì)”(其實(shí)我并不是事先設(shè)計(jì)好的),才能實(shí)現(xiàn)和同事的分工合作:我專心寫(xiě)和硬件通訊的功能;同事專心實(shí)現(xiàn)UI。

而關(guān)于MVVM這種模式,這兩天看到有人翻譯的國(guó)外一篇《ReactiveCocoa 和 MVVM 入門》的文章,終于有了一點(diǎn)初步認(rèn)識(shí)(之前看的文章,都是不明所以),文章用一個(gè)圖示說(shuō)明VM(view model)是分別從控制器“C”及視圖“V”中瘦身出來(lái)的一部分內(nèi)容(“C”的占大部分)。所以,我可以從另一個(gè)角度去理解MVVM了:VM也可以看作是對(duì)“C”瘦身出來(lái)的內(nèi)容,就類似我們的項(xiàng)目瘦身出“D”和“S”的內(nèi)容,只是大家的瘦身方式不一樣,而且VM還包含了部分“V”的內(nèi)容(不知道是否就是ReactiveCocoa這一部分涉及到的,后續(xù)再深入研究)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容