2016年5月24日 星期二

myBLE



因為公司做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];





當然,連線失敗,會從下面delegate通知我們:


-(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








沒有留言:

張貼留言