當前位置:編程學習大全網 - 編程語言 - iOS 藍牙

iOS 藍牙

1. iOS中開發藍牙常用的系統庫是<CoreBluetooth/CoreBluetooth.h>。

2.藍牙外設必需為4.0及以上(2.0需要MFI認證),否則無法進行開發,藍牙4.0設施由於低耗電,所以也叫做BLE。

3. CoreBluetooth框架的核心其實是倆東西

3.1 Peripheral

3.2?Central

4. 服務和特征(service characteristic):簡而言之,外部藍牙中它有若幹個服務service(服務妳能了解為藍牙所擁有的可以力),而每個服務service下擁有若幹個特征characteristic(特征妳能了解為解釋這個服務的屬性)。

5. Descriptor(形容)使用來形容characteristic變量的屬性。例如,壹個descriptor能規定壹個可讀的形容,或者者壹個characteristic變量可接受的範圍,或者者壹個characteristic變量特定的單位。

?3.1 創建壹個CBCentralManager實例來進行藍牙管理;

?3.2 搜索掃描外圍設備;

?3.3 連接外圍設備;

?3.4 獲得外圍設備的服務;

?3.5 獲得服務的特征;

?3.6 從外圍設備讀取數據;

?3.7 給外圍設備發送(寫入)數據。

?4.1 初始化

dispatch_queue_t centralQueue = dispatch_queue_create(“centralQueue",DISPATCH_QUEUE_SERIAL);

NSDictionary *dic = @{CBCentralManagerOptionRestoreIdentifierKey : restoreIdentifier};

self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:centralQueue options:dic];

CBCentralManagerOptionRestoreIdentifierKey對應的是壹個唯壹標識的字符串,用於藍牙進程被殺掉恢復連接時使用

4.2 掃描

/*

?*掃描設備

?*/

- ( void )scanForDevices:(NSError**)error

{

if (CBCentralManagerStatePoweredOn == self .centralManager.state) {

//取回已連接的service設備

NSArray* retrievedPeripherals = [ self .centralManagerretrieveConnectedPeripheralsWithServices:@[ self .serviceUUID]];

for (CBPeripheral* peripheral in retrievedPeripherals){

//NSLog(@"retrieved peripheral:%@", peripheral);

[ self .delegateclient: self didDiscoverDevice:peripheral.identifier];

}

//啟動掃描

if ( self .advertisementUUID) {

[ self .centralManager scanForPeripheralsWithServices:@[ self .advertisementUUID ] options:@{ CBCentralManagerScanOptionAllowDuplicatesKey:@YES }];

} else {

[ self .centralManager scanForPeripheralsWithServices: nil options:@{ CBCentralManagerScanOptionAllowDuplicatesKey:@YES }];

// [self.centralManager scanForPeripheralsWithServices:nil options:nil];

}

} else {

if (error != NULL ) {

*error = [NSErrorerrorWithDomain:HCErrorDomaincode:(SRVClientErrorUnknown+ self .centralManager.state)userInfo: nil ];

NSLog(@"[NSError errorWithDomain:HCErrorDomain code:(SRVClientErrorUnknown + self.centralManager.state) userInfo:nil];");

}

}

}

4.3 發現外圍設備

- ( void )centralManager:(CBCentralManager*)centraldidDiscoverPeripheral:(CBPeripheral*)peripheraladvertisementData:(NSDictionary*)advertisementDataRSSI:(NSNumber*)RSSI {

NSString*peripheralName = peripheral.name;

if (peripheralName == nil || peripheralName.length==0) {

return ;

}

if ([peripheralNameisEqualToString:SRV_CLIENT_DEV_NAME] || [peripheralNameisEqualToString:SRV_CLIENT_DFU_NAME]) {

}

}

4.4 連接外圍設備

//藍牙連接成功回調

- ( void )centralManager:(CBCentralManager*)centraldidConnectPeripheral:(CBPeripheral*)peripheral {

[ self .centralManager stopScan];

peripheral.delegate= self ;

self .commandNo=0;

NSLog(@"[D] CentralManager Discover services.");

NSLog(@"%@", self .peripheral);

self .peripheral.delegate= self ;

[ self .peripheral discoverServices:@[ self .serviceUUID]];

NSLog(@"%@", self .serviceUUID);

//定時獲取RSSI

if ( self .needReadRSSI) {

[ self readPeripheralRSSI];

if (! self .rssiTimer) {

self .rssiTimer = [NSTimer scheduledTimerWithTimeInterval:5.0

? target: self

selector: @selector (readPeripheralRSSI)

userInfo: nil

repeats: YES ];

}

}

}

#pragma?mark?連接外設——失敗

-?(void)centralManager:(CBCentralManager?*)central?didFailToConnectPeripheral:(CBPeripheral?*)peripheral?error:(NSError?*)error{

NSLog(@"%@",?error);

}

#pragma?mark?取消與外設的連接回調

-?(void)centralManager:(CBCentralManager?*)central?didDisconnectPeripheral:(CBPeripheral?*)peripheral?error:(NSError?*)error{

NSLog(@"%@",?peripheral);

}

4.5?獲得外圍設備的服務

//發現服務的回調

- ( void )peripheral:(CBPeripheral*)peripheraldidDiscoverServices:(NSError*)error

{

NSLog(@"%@---didDiscoverServices",peripheral);

if (error){

NSLog(@"[E] peripheral didDiscoverServices error: %@", error.localizedDescription);

[ self cancelConnection];

return ;

}

for (CBService* service in peripheral.services){

NSLog(@"[D] Discover characteristics. For service = %@", service);

[peripheraldiscoverCharacteristics: nil forService:service];

}

}

//發現特征的回調

- ( void )peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error

{

if (error){

NSLog(@"[E] peripheral didDiscoverCharacteristicsForService error: %@", error.localizedDescription);

[ self cancelConnection];

return ;

}

NSLog(@"[D] peripheral DiscoverCharacteristics = %@", service.characteristics);

//訂閱特征

for (CBCharacteristic*characteristic in service.characteristics){

if (characteristic.properties & (CBCharacteristicPropertyNotify|CBCharacteristicPropertyIndicate)){

if (!characteristic.isNotifying) {

if ([ self .ignoreCharacteristicUUIDscontainsObject:characteristic.UUID]) {

continue ;

}

NSLog(@"[D] Enable notify value. For characteristic = %@", characteristic);

//d訂閱特性當數據頻繁改變時用 setNotifyValue 不頻繁時用readValueForCharacteristic

[peripheralsetNotifyValue: YES forCharacteristic:characteristic];

}

}

}

}

// 訂閱後的callback

- ( void )peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error

{

if (error){

NSLog(@"[E] peripheral didUpdateNotificationStateForCharacteristic error: %@", error.localizedDescription);

[ self cancelConnection];

return ;

}

if ([ self isAllCharacteristicNotificationEnabled]){

NSLog(@"訂閱成功");

//authorizeRequest 授權認證

[ self .delegate clientDidPrepareForOperation: self ];

}

// [self.delegate clientDidPrepareForOperation:self];

}

4.6?從外圍設備讀取數據

// peripheral主動發數據,包括寫命令後主動返回的狀態 讀數據的回調

- ( void )peripheral:(CBPeripheral*)peripheraldidUpdateValueForCharacteristic:(CBCharacteristic*)characteristicerror:(NSError*)error

{

if (error) {

NSLog(@"[E] peripheral didUpdateValueForCharacteristic error: %@ %@", error.localizedDescription,characteristic);

[ self cancelConnection];

[ self cleanupOperationUnexpectedly];

return ;

}

NSLog(@"%@",peripheral);

NSLog(@"%@",characteristic);

[ self .delegate client: self didUpdateValueForCharacteristic:characteristic.UUID value:characteristic.value];

if ([characteristic.UUIDisEqual: self .ctrlptUUID]) {

if (CTRLPTProgressWaitResp == self .ctrlptProgress) {

? }

}

?}

4.7?給外圍設備發送(寫入)數據

- ( BOOL )performOperationSegment:(CBCharacteristic*)characteristic

{

BOOL isLastSegment;

uint8_tsegment[20];

uint16_tindex =0;

uint16_tsegLength;

NSIntegerforwardLength = self .forwardFlow.length;

if ((forwardLength - self .forwardOffset) > (20- index)) {

isLastSegment = NO ;

segLength = (20- index);

} else {

isLastSegment = YES ;

segLength = (forwardLength - self .forwardOffset);

}

memcpy(&segment[index], & self .forwardFlow.bytes[ self .forwardOffset], segLength);

self .forwardOffset+= segLength;

index += segLength;

NSData*writeData = [NSDatadataWithBytes:segmentlength:index];

NSLog(@"[D] Write value = %@. For characteristic = %@", writeData, characteristic);

[ self .peripheral writeValue:writeData forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];//對於操控類藍牙,數據寫入要求非常快,其中writeWithSponce寫入消耗的時間是writeWithoutSponce的2.3倍,因此盡量改寫成writeWithoutSponce來提升寫入速率

return isLastSegment;

?}

//是否寫入成功的回調

- ( void )peripheral:(CBPeripheral*)peripheraldidWriteValueForCharacteristic:(CBCharacteristic*)characteristicerror:(NSError*)error

{

if (error) {

NSLog(@"[E] peripheral didWriteValueForCharacteristic error: %@", error);

[ self cancelConnection];

[ self cleanupOperationUnexpectedly];

return ;

}

NSLog(@"寫入成功----%@",characteristic);

if ([characteristic.UUIDisEqual: self .ctrlptUUID]) {

if (CTRLPTProgressWritting == self .ctrlptProgress) {

if ([ self performOperationSegment:characteristic]) {

self .ctrlptProgress = CTRLPTProgressWaitResp;

self .backwardFlow.length=0;

self .backwardOffset=0;

}

}

}

}

4.8 如何解析藍牙數據

//判斷是否第壹個包,若是,取出包長度

if (0== self .backwardOffset&& length >=2) {

uint16_tcommandLength;

[characteristicDatagetBytes:&commandLengthlength: sizeof (commandLength)];

offset += sizeof (commandLength);

self .backwardLength= commandLength;

[ self .backwardFlowappendData:[characteristicDatasubdataWithRange:NSMakeRange(offset, length - offset)]];

} else {

[ self .backwardFlowappendData:characteristicData];

}

  • 上一篇:雄獅編程
  • 下一篇:如何培養初中生學習信息技術的興趣
  • copyright 2024編程學習大全網