雖然做藍牙項目有一段時間了颁井,最近才真正的接觸藍牙模塊。剛開始寫了個作為中心設(shè)備的demo蠢护,發(fā)現(xiàn)周圍硬件太多雅宾,也不知道哪個是哪個了,所以就又寫了個作為外設(shè)管理器的demo葵硕,參考的是http://liuyanwei.jumppo.com/2015/09/07/ios-BLE-3.html眉抬。
好了,說說我的思路吧懈凹。
1蜀变、創(chuàng)建外圍設(shè)備CBPeripheralManager對象
self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil];
queue:表示的是分派事件的隊列,外設(shè)的事件將在提供的隊列上分派介评,如果設(shè)為nil库北,將使用主隊列。
當(dāng)創(chuàng)建了peripheralManager后们陆,和中心設(shè)備一樣寒瓦,會調(diào)用一個- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral的方法,這個方法必須實現(xiàn)坪仇。
2杂腰、給外設(shè)添加服務(wù)與特征
用CBMutableCharacteristic的initWithType:properties:value:permissions來創(chuàng)建特征,根據(jù)自己的需求寫定特征的UUID椅文、值和許可喂很。
// 可通知的特征
CBMutableCharacteristic *notifyCharacteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:KBNotiyCharacteristicUUID] properties:CBCharacteristicPropertyNotify value:nil permissions:CBAttributePermissionsReadable];
// 可讀寫的特征
CBMutableCharacteristic *readAndWriteCharacteristic = [[CBMutableCharacteristic alloc]initWithType:[CBUUID UUIDWithString:KBReadAndWriteCharacteristicUUID] properties:CBCharacteristicPropertyWrite | CBCharacteristicPropertyRead value:nil permissions:CBAttributePermissionsReadable | CBAttributePermissionsWriteable];
// service初始化加入兩個characteristics
CBMutableService *service = [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:KBKBServiceUUID] primary:YES];
[service setCharacteristics:@[notifyCharacteristic,readAndWriteCharacteristic]];
// 將服務(wù)及其關(guān)聯(lián)的特性發(fā)布到本地數(shù)據(jù)庫
// 在調(diào)用addService方法后惜颇,會調(diào)用peripheralManager:didAddService:error:方法
[self.peripheralManager addService:service];
3、成功把服務(wù)和特征添加到數(shù)據(jù)庫中后少辣,開始廣播外設(shè)的服務(wù)或特征凌摄,調(diào)用startAdvertising:方法,使centralManager可以掃描到此外設(shè)毒坛。
[self.peripheralManager startAdvertising:@{
CBAdvertisementDataServiceUUIDsKey:@[[CBUUID UUIDWithString:KBServiceUUID]],
CBAdvertisementDataLocalNameKey:KBPeripheralLocalNameKey
}];
startAdvertising: 后面的參數(shù)是個字典類型望伦,里面放入需要廣播的數(shù)據(jù),具體的可以看CBAdvertisementData.h煎殷,但是對于我們創(chuàng)建的藍牙外設(shè)管理器,我們只能廣播這兩個key “CBAdvertisementDataLocalNameKey”和“?CBAdvertisementDataServiceUUIDsKey”腿箩。
當(dāng)外設(shè)開始廣播時豪直,會調(diào)用代理peripheralManagerDidStartAdvertising:error:。
4珠移、連上中心設(shè)備后的響應(yīng)
當(dāng)中心設(shè)備連上此外設(shè)弓乙,會對外設(shè)的讀、寫钧惧、監(jiān)聽的特征進行讀暇韧、寫、監(jiān)聽的操作浓瞪,作為外設(shè)管理器懈玻,需要對這些請求作出回應(yīng)。
1)收到中心設(shè)備讀特征請求后的回應(yīng)
中心設(shè)備對可讀的特征進行讀請求時乾颁,會調(diào)用代理peripheralManager:didReceiveReadRequest:涂乌。根據(jù)傳入的CBATTRequest對象的特征的properties屬性是否可讀,如果滿足英岭,可以通過外設(shè)的特征的值賦給請求的值(默認(rèn)是nil)湾盒,并告訴中心設(shè)備已經(jīng)設(shè)置成功,調(diào)用CBPeripheralManager的respondToRequest:withResult:的方法诅妹。
//判斷是否有讀數(shù)據(jù)的權(quán)限
if (request.characteristic.properties & CBCharacteristicPropertyRead) {
NSData *data = request.characteristic.value;
[request setValue:data];
//對請求作出成功響應(yīng)
[peripheralManager respondToRequest:request withResult:CBATTErrorSuccess];
}
但是罚勾,如果不滿足,也需要調(diào)用respondToRequest:withResult:的方法吭狡,給中心設(shè)備反饋一個失敗的原因尖殃。
[self.peripheralManager respondToRequest:request withResult:CBATTErrorWriteNotPermitted];
2)收到中心設(shè)備寫特征請求后的回應(yīng)
中心設(shè)備對可寫的特征進行寫請求時,會調(diào)用代理peripheralManager:didReceiveWriteRequests:赵刑。和讀的請求回應(yīng)差不多分衫,也需要去判斷CBATTRequest對象的特征的properties是否滿足可寫的,可能會有多個請求對象般此,requests是個數(shù)組蚪战,取傳入數(shù)組中的第一個請求作為參數(shù)牵现,如果滿足,寫入值邀桑,
CBATTRequest *request = requests[0];
//轉(zhuǎn)換成CBMutableCharacteristic對象才能進行寫值
CBMutableCharacteristic *characteristic =(CBMutableCharacteristic *)request.characteristic;
characteristic.value = request.value;
[self.peripheralManager respondToRequest:request withResult:CBATTErrorSuccess];
如果不滿足的話瞎疼,調(diào)用respondToRequest:withResult:的方法,給中心設(shè)備反饋一個失敗的原因壁畸。
[self.peripheralManager respondToRequest:request withResult:CBATTErrorWriteNotPermitted];
注意:對于多個請求對象只有一次請求,只要任意的一個請求對象得不到滿足,你任意一個都不要滿足,而是立即調(diào)用respondToRequest:withResult:方法提供一個結(jié)果,告訴失敗的原因.
3)收到中心設(shè)備訂閱請求后的回應(yīng)
當(dāng)中心設(shè)備訂閱一個或多個特征值的話贼急,外設(shè)需要將發(fā)生改變的特征值告訴中心設(shè)備,調(diào)用代理peripheralManager:central:didSubscribeToCharacteristic:捏萍。在代理方法中獲取最新的特征值并調(diào)用updateValue:forCharacteristic:onSubscribedCentrals:方法向中心設(shè)備發(fā)送數(shù)據(jù)太抓。如果失敗,會調(diào)用代理peripheralManagerIsReadyToUpdateSubscribers:令杈,可在該代理中再次傳送數(shù)據(jù)走敌。
取消訂閱的話,調(diào)用代理peripheralManager:central:didUnsubscribeFromCharacteristic:逗噩。
嗯掉丽,就到這了,可能有些地方寫的不夠?qū)I(yè)异雁,也希望大家指正捶障,謝謝!