ios蓝牙交互部分

https://cdking.github.io/iOS-BLE.io/

懒人逻辑理解:蓝牙发射分外围设备(发射)和中心设备(接收)

基本的层次关系:设备-管理器-服务-特征-值。(管理器开始一对多)

< 一 > 蓝牙发射端(外围设备)

#import

1)一个外围设备管理器

CBPeripheralManager *peripheralMgr;

peripheralMgr = [[CBPeripheralManager alloc]initWithDelegate:self queue:nil];

// 当外围设备管理器被实例化后,协议函数peripheralManagerDidUpdateState会被调用

2)管理器状态管理

-(void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral

{

    // 判断蓝牙设备状态

    // iOS 10 的状态判断

    if (peripheral.state == CBManagerStatePoweredOn) {

        // 蓝牙可以正常使用且已打开

  // 这是一个设置下一步的方法,详情请看3)

        [self setUpBlueTooth];

    }else{

        // 蓝牙设备无法正常使用或未打开

    }

    

    // iOS 10 以前的状态判断 就是设备蓝牙状态的判断名称变化了而已

    /*

    if (peripheral.state == CBPeripheralManagerStatePoweredOn) {

        // 蓝牙可以正常使用且已打开

    }else{

        // 蓝牙设备无法正常使用或未打开

    }

     */

}

3)搭建服务

-(void)setUpBlueTooth

{

    // 假数据

    NSData *dummyData = [@"HelloWorld" dataUsingEncoding:NSUTF8StringEncoding];

    // 特征的搭建

 // 有读,写,订阅 三种,如果value不为空则不能只能读与订阅(订阅和读类似)

 // UUID 我是完全瞎写的= =

    CBMutableCharacteristic *character = [[CBMutableCharacteristic alloc]initWithType:[CBUUID UUIDWithString:@"AAAAAAAA-E798-4D5C-8DCF-49908332DF9F"] properties:CBCharacteristicPropertyRead value:dummyData permissions:CBAttributePermissionsReadable];

// 写分WithoutResponse和WithResponse,蓝牙的中心与外围必须一致

    CBMutableCharacteristic *character2 = [[CBMutableCharacteristic alloc]initWithType:[CBUUID UUIDWithString:@"AAAAAAAA-E798-4D5C-8DCF-49908332DF8F"] properties:CBCharacteristicPropertyWriteWithoutResponse value:nil permissions:CBAttributePermissionsWriteable];

    // 特征加入服务中

    service = [[CBMutableService alloc]initWithType:[CBUUID UUIDWithString:@"BBBBBBBB-6525-4489-801C-1C060CAC9767"] primary:YES];

    [service setCharacteristics:@[character,character2]];

    // 服务加入管理中 回调didAddService协议方法

    [peripheralMgr addService:service];

}

4)发射广播

-(void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error

{

    if (error) {

        // 发生错误未能成功添加服务

    }else{

        [peripheralMgr startAdvertising:@{

                                          CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:@"CCCCCCCC-E798-4D5C-8DCF-49908332DF9F"]],

            // 这是广播名称,可以作为中心设备接收判断的Flag

                                          CBAdvertisementDataLocalNameKey : @"GoodGoodStudyDaydayUp"

                                          }];

    }

}

// 广播发射之后会走楼下的协议回调方法

-(void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(NSError *)error

{

    if (error) {

        // 发送服务错误

    }else{

        // 发送服务成功

    }

}

5)读写请求的接收

读请求 didReceiveReadRequest 回调方法

写请求 didReceiveWriteRequests 回调方法

// 得到写请求的详细数据看楼下

- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray *)requests{

    NSLog(@"收到写数据请求: %@",peripheral);

    NSLog(@"数据请求: %@ , %lu",requests[0],(unsigned long)requests.count);

    CBATTRequest *request = requests[0];

    CBCharacteristic *cbs = request.characteristic;

    NSLog(@"噢啦啦啦啦啦 : %@",cbs.UUID.description);

    NSString*hahah = [[NSString alloc]initWithData:request.value encoding:NSUTF8StringEncoding];

    NSLog(@"哇哈哈哈哈哈  :%@",hahah);

}

6)变更(被订阅)内容

[Manager updateValue:Data forCharacteristic:kkk onSubscribedCentrals:nil];

// 变更后会走楼下的回调函数

- (void)peripheralManagerIsReadyToUpdateSubscribers:(CBPeripheralManager *)peripheral{

    // 准备更新订购者

}

==================================================================================================================================================================================================================================================================

< 二 > 蓝牙接收端(中心设备)

发射时一层一层包装好了发出去,接收当然就是一层一层拿下来的收回来啦!

#import

1)一个中心管理器

CBCentralManager *centralMgr;

// 楼下的也一般声明一下意思意思

// 用于存储设备信息(苹果要求)

    NSMutableArray* peripheralMutableArray;

    NSMutableArray* RSSRMutableArray;

// 目标设备

    CBPeripheral *targetPeripheral;

// 初始化后centralManagerDidUpdateState执行

    centralMgr = [[CBCentralManager alloc]initWithDelegate:self queue:nil];

2)管理器状态管理

-(void)centralManagerDidUpdateState:(CBCentralManager *)central

{

    // 判断设备蓝牙状态 iOS 10 前后

    /*

    if (central.state == CBCentralManagerStatePoweredOn) {

    }else{

    }

     */

    if (central.state == CBManagerStatePoweredOn) {

        // 设备蓝牙状态可用

        // 设备可用,开始搜索周围设备,之后发现设备后会执行didDiscoverPeripheral回调方法

        [centralMgr scanForPeripheralsWithServices:nil options:nil];

    }else{

        // 设备蓝牙状态异常,请开启蓝牙或检查设备蓝牙是否可用

    }

}

3)寻找目标

------> 找设备

-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI

{

// 苹果要的。。。

    [peripheralMutableArray addObject:peripheral];

    [RSSRMutableArray addObject:RSSI];

    // 获取广播名称

    NSString* adName = [advertisementData objectForKey:@"kCBAdvDataLocalName"];

    NSLog(@"广播名称:%@",adName);

    // 获取外围设备信息

    NSLog(@"外围设备信息:%@",peripheral);

    

    if ([adName isEqualToString:@"GoodGoodStudyDaydayUp"]) {

        // 发现目标设备,开始连接。结果会通过回调函数返回

        // 开始连接目标设备,结果看楼下的函数

        [centralMgr connectPeripheral:peripheral options:nil];

    }

}

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

{

   // 连接外围设备失败

}

 

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

{

    // 断开外围设备连接

}

// 

-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral

{

    NSLog(@"设备连接成功:%@",peripheral.description);

    

    targetPeripheral = peripheral;

    

    // 搜索设备内服务,发现后didDiscoverServices调用

    [peripheral setDelegate:self];

    [peripheral discoverServices:nil];

}

------> 找服务

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

{

    if (error) {

        NSLog(@"扫描服务失败:%@",error);

    }

    else{

        NSLog(@"扫描到了服务个数:%lu",(unsigned long)peripheral.services.count);

        for (CBService* service in peripheral.services) {

            NSLog(@"被扫描到的服务:%@",service.UUID);

    // 这些UUID啥的看业务了

            if ([service.UUID.UUIDString isEqualToString:@"BBBBBBBB-6525-4489-801C-1C060CAC9767"]) {

                // 发现目标服务

                // 搜索服务,结果在楼下的回调函数调用中体现

                [peripheral discoverCharacteristics:nil forService:service];

            }

        }

    }

}

------> 找特征

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

{

    if (error) {

        NSLog(@"搜索设备特征失败:%@",error);

    }

    else{

        NSLog(@"%@的特征个数:%ld",service.UUID,(unsigned long)service.characteristics.count);

        for (CBCharacteristic* character in service.characteristics) {

            NSLog(@"%@的character:%@",service.UUID,character.UUID);

            if ([character.UUID.description isEqualToString:@"AAAAAAAA-E798-4D5C-8DCF-49908332DF9F"]) {

                NSLog(@"发现目标特征");

                // 读特征

                [peripheral readValueForCharacteristic:character];

            }else if ([character.UUID.description isEqualToString:@"AAAAAAAA-E798-4D5C-8DCF-49908332DF8F"]){

                // 读到特征

                [peripheral readValueForCharacteristic:character];

            }

  // 订阅的话就订阅

//            if ([character.UUID.description isEqualToString:@"??????"]) {

//                [peripheral setNotifyValue:YES forCharacteristic:character];

                //                [peripheral discoverDescriptorsForCharacteristic:character];

//            }

        }

    }

}

------> 找值

// 读与订阅都会走楼下的方法

-(void)peripheral:(CBCentralManager *)peripheral didUpdateValueForCharacteristic:(nonnull CBCharacteristic *)characteristic error:(nullable NSError *)error

{

    // 发现目标特征值更新

    NSLog(@"发现目标特征值更新:%@",characteristic.UUID.description);

    // 获取值

    NSString *str = [[NSString alloc]initWithData:characteristic.value encoding:NSUTF8StringEncoding];

    NSLog(@"获取目标值:%@",str);

    // 假如我需要写数据了的话

    if ([characteristic.UUID.description isEqualToString:@"AAAAAAAA-E798-4D5C-8DCF-49908332DF8F"]) {

        // 写数据

        NSLog(@"写数据中。。。");

        NSData *writeData  = [@"世界你好" dataUsingEncoding:NSUTF8StringEncoding];

  // 写完数据后会走到外围设备的对应回调函数中(看第一部分的5))

        [targetPeripheral writeValue:writeData forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];

    }

}

啰嗦:基本的就是这样,BLE4.0。发射的话,可以让自己的值0.01秒这样的疯狂变化,只要是withoutresponse,接收端就不会出现数据丢失的情况

 

转载于:https://www.cnblogs.com/reyalPDC/p/6379362.html

你可能感兴趣的:(ios蓝牙交互部分)