因為公司做beacon的,所以,自然就會碰到藍牙,而且還是一直碰一直碰的,
早該寫這一篇,現在算是複習吧xd~
另外會把一些該注意的部份分享一下
首先,基礎設置:
設定是否在app進入背景後使用藍牙
加入最重要的framework
藍牙在ios可以分成兩部分:central端,和peripheral端,
照例,不多解釋細節,有興趣可以在網路上查找,很多大神都已經有很清楚的解釋,我也自
認無法解釋更好了xd~
藍牙,其實依照delegate,可以先簡單分成幾個部分:
1.掃描
2.連線
3.找到最重要的characteristic
4.讀寫characteristic
5.斷線
首先,就central部分:
先設好delegate
<CBCentralManagerDelegate,CBPeripheralDelegate>
之後
centralmanager別忘了給他設定delegate
centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
1.掃描:
下達掃描:
NSArray * services = @[];
NSDictionary *options = @{CBCentralManagerScanOptionAllowDuplicatesKey:@true};
[centralManager scanForPeripheralsWithServices:services options:options];
至於為何要設置這些?可以上網查找,很多人解試過了,基本上就是說,首先,我沒有要scan特定的service,所以直接給他一個空的array,請他全部都scan,如果有要scan特定的service,這邊就要設定,之後的dictionary,是指說,就算是掃描到一樣的廣告封包(下面會說),也請吐給我,當然這樣做會是比較耗電的
如果要app一進入就開始直接掃描,最好是在viewDidAppear,或是在centralManagerDidUpdateState這邊讓他去scan,否則無法一進入就掃描
掃描之後呢!?會在下面這個delegate,將掃描到的廣告封包,吐給我們,讓我們可以對他ooxx,就是可以做先期處理就是了xd~
-(void) centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI
2.連線
當下達:connectPeripheral:options:,
之後,如果順利連線到我們指定的peripheral,會在下面這個delegate通知我們:
-(void) centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
這時候,可以停止上面的掃描
給peripheral設定delegate:
peripheral.delegate = self;
並且,請peripheral去查找連線上的peripheral的所有的service
[peripheral discoverServices:nil];
下達上面之後,如果順利查找到service,會利用下面的delegate通知我們:
-(void) peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
這時候,可以看從特定的service去查找我們要處理的characteristic,
或是把service掃出來之後,去全部找出所有service裡面的所有的characteristic:
[peripheral discoverCharacteristics:nil forService:targetService];
-(void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
可以再去做處理
3.找到最重要的characteristic
當上面下達之後(discoverCharacteristics),會利用下面的delegate通知我們
-(void) peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
這時候就可以把characteristic掃出來,然後去一個個做處理
for (CBCharacteristic *tmpCharacteristic in service.characteristics
=================我是分隔線================
ok,到這邊,暫停一下,到了這一步,算是已經差不多了,但是有些小重點要注意一下,
首先,我們不一定會在同一個controller做處理,或是掃描之後連線,這時候,不建議用
segue去做跳轉,再來,我在samplecode是把peripheral存起來,跳轉後去連線,
但是!!!一樣不建議用這種偷懶的方法來處理!!!最好是在掃描時
-(void) centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI
這個callback,拿到的
peripheral.identifier.UUIDString;
把它存起來,
如果到其他controller做連線時,
讓他去依照
if ([peripheral.identifier.UUIDString isEqualToString:self.foundItem.talkingUUID.UUIDString])
一樣的字串,去做連線
=================我是分隔線================
4.讀寫characteristic
當上面去掃出所有的characteristic之後([peripheral discoverCharacteristics:nil forService:),會在下面的delegate吐給我們所有的characteristic:
-(void) peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
這時候可以針對每一個特定的characteristic,去做讀,寫:
注意,這時候可以看其他大神的解釋,總之就是說,characteristic有分成可讀,可寫,或是當他的值有改變的時候,會利用通知,來通知我們的
如果是通知,會從通知的delegate來通知我們
首先,如果是想要能夠讀到,或是得到通知,必須要針對我們上面拿到的characteristic來做設定:
讀:
[specificPeripheral readValueForCharacteristic:_characteristic];
通知:
[specificPeripheral setNotifyValue:true forCharacteristic:_characteristic];
讀:
之後,會在下面的delegate來給我們,之後就可以去對nsdata做處理了
-(void) peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
ex:
NSData *data0 = [NSData dataWithData:_characteristic.value];
通知:
會在下面的delegate來通知我們:
-(void) peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
同上,之後就可以對他的value,取得的nsdata來做處理
寫:
注意的是,不管寫啥東西,都要轉成nsdata,之後才可以順利寫入:
[Peripheral writeValue:data
forCharacteristic:_characteristic
type:CBCharacteristicWriteWithResponse];
解說:針對Peripheral寫入data,對那一個_characteristic,然後他在寫入時,會有分成
CBCharacteristicWriteWithResponse或是沒有回應:CBCharacteristicWriteWithoutResponse
有回應的,會在下面的delegate,讓我們知道是否寫入成功:
-(void) peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
5.斷線
會在下面的delegate讓我們知道
-(void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
沒有留言:
張貼留言