剛開(kāi)始接觸藍(lán)牙App的開(kāi)發(fā)時(shí),采用的是系統(tǒng)提供的CoreBluetooth,各種代理方法,代碼冗余且順序凌亂,于是在github里找到了BabyBluetooth一個(gè)簡(jiǎn)單易用的藍(lán)牙庫(kù),基于CoreBluetooth的封裝。
使用BabyBluetooth的原因:
1:基于原生CoreBluetooth框架封裝的輕量級(jí)的開(kāi)源庫(kù),可以幫你更簡(jiǎn)單地使用CoreBluetooth API。
2:CoreBluetooth所有方法都是通過(guò)委托完成,代碼冗余且順序凌亂。BabyBluetooth使用block方法,可以重新按照功能和順序組織代碼,并提供許多方法減少藍(lán)牙開(kāi)發(fā)過(guò)程中的代碼量。
3:鏈?zhǔn)椒椒w,代碼更簡(jiǎn)潔、優(yōu)雅。
4:通過(guò)channel切換區(qū)分委托調(diào)用,并方便切換
5:便利的工具方法
6:完善的文檔,且項(xiàng)目處于活躍狀態(tài),不斷的更新中
7:github上star最多的純Bluetooch類(lèi)庫(kù)(非PhoneGap和SensorTag項(xiàng)目)
8: 包含多種類(lèi)型的demo和ios藍(lán)牙開(kāi)發(fā)教程
下面就講一下在使用BabyBluetooth的過(guò)程中,自己所理解的一些東西。
在理解BabyBluetooth的源碼后,心中不自覺(jué)的就會(huì)產(chǎn)生這么一個(gè)想法:自己在把BabyBluetooth封裝一下。不知道大多數(shù)程序員是不是也有同樣的感受,當(dāng)拿到別人封裝的代碼模塊時(shí),總想自己在重新封裝一下。
當(dāng)時(shí)還沒(méi)有根據(jù)項(xiàng)目的需求好好的理解藍(lán)牙模塊該如何編寫(xiě),自己就新建了一個(gè)BabaBluetoothManager類(lèi)(還使用了單例模式)。
后來(lái)在開(kāi)發(fā)的過(guò)程中,就發(fā)現(xiàn)這樣的處理方法簡(jiǎn)直糟糕透了。
錯(cuò)誤一:BabaBluetoothManager的創(chuàng)建,隨意的二次封裝。
理解:在開(kāi)發(fā)的過(guò)程中,二次封裝前,一定要考慮清楚二次封裝會(huì)帶來(lái)什么好處,有沒(méi)有必要進(jìn)行二次封裝。如果處理不當(dāng),不僅浪費(fèi)開(kāi)發(fā)時(shí)間,是代碼層層嵌套,增加代碼的復(fù)雜性。
錯(cuò)誤二:BabyBluetooth在創(chuàng)建對(duì)象的時(shí)候使用的單例
后果:由于項(xiàng)目中多個(gè)模塊都會(huì)進(jìn)行藍(lán)牙的搜索、連接、讀取,在每個(gè)模塊都會(huì)設(shè)置babyBluetooth的各種Block,這就會(huì)造成Block被重新賦值,其它模塊的Block就會(huì)失效。
理解:項(xiàng)目中在使用單例對(duì)象之前,一定要考慮該對(duì)象是不是全局統(tǒng)一的。如果各個(gè)功能模塊共用某一對(duì)象的屬性及方法,這種情況下可以使用單例,反之各個(gè)功能模塊操作某一對(duì)象的屬性方法時(shí)不希望受其他模塊的影響,就不適合采用單例對(duì)象。
在項(xiàng)目中,多個(gè)頁(yè)面都需要對(duì)藍(lán)牙進(jìn)行搜索、連接、讀取,當(dāng)某一頁(yè)面對(duì)藍(lán)牙進(jìn)行搜索時(shí),任希望其他頁(yè)面正常的對(duì)已連接的藍(lán)牙讀取數(shù)據(jù),這樣BabyBluetooth采用單例就不適合了。
其他注意點(diǎn):
1、開(kāi)始搜索:
babyBluetooth.scanForPeripherals().begin()```
2、取消搜索
```BabyBluetooth*babyBluetooth = [[BabyBluetooth alloc]init];
[babyBluetooth cancelScan];```
3、連接設(shè)備
```BabyBluetooth*babyBluetooth = [[BabyBluetooth alloc]init];
babyBluetooth.having(peripheral).and.channel(channel).then.connectToPeripherals().discoverServices().discoverCharacteristics().readValueForCharacteristic().discoverDescriptorsForCharacteristic().readValueForDescriptors().begin();```
4、讀取characteristics數(shù)據(jù)
[self.bluetooth setBlockOnReadValueForCharacteristicAtChannel:NSStringFromClass([self class]) block:^(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error) {
//特別重要
if([characteristics.UUID.UUIDString isEqualToString:@"FFE1"]){
if(![characteristics isNotifying]){
[peripheral setNotifyValue:YES forCharacteristic:characteristics];
NSLog(@"開(kāi)始監(jiān)聽(tīng)");
}
NSData *data = characteristics.value;
//溫度、濕度、光照、肥力
NSLog(@"讀取%@特征value is:%@",characteristics.UUID.UUIDString,data);
XHNotifiedModel *model = [weakSelf.gardenViewModel notifedModelWithNotifiedValue:data];
NSLog(@"%@",model);
if(model!=nil){
weakSelf.environmentView.model = model;
}
}
}]; ```