美文网首页iOS开发精进
使用BabyBluetooth进行蓝牙连接

使用BabyBluetooth进行蓝牙连接

作者: 静谧无际 | 来源:发表于2016-09-20 16:58 被阅读5007次

    刚开始接触蓝牙App的开发时,采用的是系统提供的CoreBluetooth,各种代理方法,代码冗余且顺序凌乱,于是在github里找到了BabyBluetooth一个简单易用的蓝牙库,基于CoreBluetooth的封装。

    使用BabyBluetooth的原因:
    1:基于原生CoreBluetooth框架封装的轻量级的开源库,可以帮你更简单地使用CoreBluetooth API。
    2:CoreBluetooth所有方法都是通过委托完成,代码冗余且顺序凌乱。BabyBluetooth使用block方法,可以重新按照功能和顺序组织代码,并提供许多方法减少蓝牙开发过程中的代码量。
    3:链式方法体,代码更简洁、优雅。
    4:通过channel切换区分委托调用,并方便切换
    5:便利的工具方法
    6:完善的文档,且项目处于活跃状态,不断的更新中
    7:github上star最多的纯Bluetooch类库(非PhoneGap和SensorTag项目)
    8: 包含多种类型的demo和ios蓝牙开发教程

    下面就讲一下在使用BabyBluetooth的过程中,自己所理解的一些东西。
      在理解BabyBluetooth的源码后,心中不自觉的就会产生这么一个想法:自己在把BabyBluetooth封装一下。不知道大多数程序员是不是也有同样的感受,当拿到别人封装的代码模块时,总想自己在重新封装一下。

    当时还没有根据项目的需求好好的理解蓝牙模块该如何编写,自己就新建了一个BabaBluetoothManager类(还使用了单例模式)。

    后来在开发的过程中,就发现这样的处理方法简直糟糕透了。

    错误一:BabaBluetoothManager的创建,随意的二次封装。

    理解:在开发的过程中,二次封装前,一定要考虑清楚二次封装会带来什么好处,有没有必要进行二次封装。如果处理不当,不仅浪费开发时间,是代码层层嵌套,增加代码的复杂性。

    错误二:BabyBluetooth在创建对象的时候使用的单例

    后果:由于项目中多个模块都会进行蓝牙的搜索、连接、读取,在每个模块都会设置babyBluetooth的各种Block,这就会造成Block被重新赋值,其它模块的Block就会失效。

    理解:项目中在使用单例对象之前,一定要考虑该对象是不是全局统一的。如果各个功能模块共用某一对象的属性及方法,这种情况下可以使用单例,反之各个功能模块操作某一对象的属性方法时不希望受其他模块的影响,就不适合采用单例对象。

    在项目中,多个页面都需要对蓝牙进行搜索、连接、读取,当某一页面对蓝牙进行搜索时,任希望其他页面正常的对已连接的蓝牙读取数据,这样BabyBluetooth采用单例就不适合了。

    其他注意点:
    1、开始搜索:

    babyBluetooth.scanForPeripherals().begin()```
    2、取消搜索
    ```BabyBluetooth*babyBluetooth = [[BabyBluetooth alloc]init];
    [babyBluetooth cancelScan];```
    
    3、连接设备
    ```BabyBluetooth*babyBluetooth = [[BabyBluetooth alloc]init];
    babyBluetooth.having(peripheral).and.channel(channel).then.connectToPeripherals().discoverServices().discoverCharacteristics().readValueForCharacteristic().discoverDescriptorsForCharacteristic().readValueForDescriptors().begin();```
    
    4、读取characteristics数据
    

    [self.bluetooth setBlockOnReadValueForCharacteristicAtChannel:NSStringFromClass([self class]) block:^(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error) {
    //特别重要
    if([characteristics.UUID.UUIDString isEqualToString:@"FFE1"]){
    if(![characteristics isNotifying]){
    [peripheral setNotifyValue:YES forCharacteristic:characteristics];
    NSLog(@"开始监听");
    }
    NSData *data = characteristics.value;
    //温度、湿度、光照、肥力
    NSLog(@"读取%@特征value is:%@",characteristics.UUID.UUIDString,data);
    XHNotifiedModel *model = [weakSelf.gardenViewModel notifedModelWithNotifiedValue:data];
    NSLog(@"%@",model);
    if(model!=nil){
    weakSelf.environmentView.model = model;
    }

        }
    }]; ```

    相关文章

      网友评论

      • 睿少:您好,请问我如何通过 mac 地址连接到设备唉?
      • Charlin丶:我使用了单例创建,如果我要在其他页面也要进行数据的收发的话,是不是都要调用setBlockOnReadValueForCharacteristic这个方法来拿读写的特性?
      • 1aec63424283:请问我怎么用babybluetooth判断蓝牙状态呢 比如说没有打开蓝牙提示用户开启
      • 349f80c66e20:请问怎么可以主动让蓝牙断开连接
      • dc480ae00a31:大神我这里接受不到数据 不走setBlockOnReadValueForCharacteristicAtChannel这个方法咋回事呢
      • Zz7777777:怎么给蓝牙发指令 你这边还记得吗
        Gavin_yangs:@HelloKids 同学,我也遇到同样的问题,不知道你是如何解决的呢?在写成功之后的 block 回调中打印了 characteristic 的 value 值为 null。
        Zz7777777:@静谧无际 我这边已经找到了有写的属性 发送指令 结果回调characteristics的value为空 能否进一步加QQ了解下
        静谧无际:@PengJiang 如果某服务的特征值具有写属性,就可以写数据,发送指令
      • 一只风流的dog:大神你好
      • 跟着内心走:如何在后台实时监听手机是否断开了蓝牙呢,为啥我在app delegate做了监听,关闭蓝牙后再打开就没有任何反应了
        qiulibi:请问你的问题解决了吗?我也遇到类似的问题。
      • ShineYangGod:怎么获取到蓝牙设备的mac地址啊?
        静谧无际:@神地创造 先读取蓝牙的所有服务,其中有一个服务是Device Information,然后读取该服务的特征值,有一个特征是SystemID,读取到该特征值,然后转换成mac就可以了
        ShineYangGod:@静谧无际 能说的详细点吗?SystemID这个在哪里获取?
        静谧无际:@神地创造
        读取"Device Information"服务中的SystemID特征值,根据SystemID计算出mac地址
        - (NSString *)macAddressWithSystemId:(NSString *)value{
        NSMutableString *macString = [[NSMutableString alloc] init];
        [macString appendString:[[value substringWithRange:NSMakeRange(16, 2)] uppercaseString]];
        [macString appendString:@":"];
        [macString appendString:[[value substringWithRange:NSMakeRange(14, 2)] uppercaseString]];
        [macString appendString:@":"];
        [macString appendString:[[value substringWithRange:NSMakeRange(12, 2)] uppercaseString]];
        [macString appendString:@":"];
        [macString appendString:[[value substringWithRange:NSMakeRange(5, 2)] uppercaseString]];
        [macString appendString:@":"];
        [macString appendString:[[value substringWithRange:NSMakeRange(3, 2)] uppercaseString]];
        [macString appendString:@":"];
        [macString appendString:[[value substringWithRange:NSMakeRange(1, 2)] uppercaseString]];
        return macString;
        }
      • 帅气的阿斌:我用的babybluetooth连接我搜索到的设备 但是在连接成功的回调里 会提示连接了其余的设备 这什么情况??????
        帅气的阿斌:我猜想 是不是不通过我自己的app连接的蓝牙也会在我的app里回调?? 而且还连接了个 air 也是醉了
        帅气的阿斌:@静谧无际 链接到了我想要的设备。然后过会又收到链接成功的回调。连接上了其他的设备..
        静谧无际:没遇到这种情况,打印一下连接的设备的信息,看看是否是你要连接的设备
      • MarAlves:大神请问为什么我连接上蓝牙设备会经常断开连接,但是安卓的就不会
        MarAlves:@烟雨笼罩了谁的身姿 我那时候是因为开了省电模式才会这样的。你可以多换几台手机测试下,有可能会是手机的问题
        烟雨笼罩了谁的身姿:@MarAlves 你的解决了吗,我也遇到这种情况了,但是硬件工程师说省电模式没有开,头疼啊
        静谧无际:@MarAlves 我当时连接蓝牙设备的时候也时常断开,后来找硬件工程师,把蓝牙设备的省电模式给关了,就好了
      • 聂飞缘:蓝牙到底是怎么收发数据的,在哪个方法里面可以看到收发的数据的呀
        聂飞缘:@静谧无际 是在write Value那个方法里面发数据给外设么
        静谧无际:接受的数据就是characteristics.value,是一串二进制数据,然后解析出来就可以了
      • 策马鞭程:应该是硬件那边没有使用notify
      • 策马鞭程:但是用一个定时器不断读取就有数据
      • 策马鞭程:打印出:uuid:FFF1,isNotifying:Notifying
        策马鞭程:@静谧无际 谢谢,我已经知道问题了,是硬件那边的问题. :blush:
        静谧无际:@策马鞭程 如果蓝牙设备没有主动发送实时数据,也不会有通知的吧
      • 策马鞭程:请问有demo吗?为什么我的接收不到通知
        静谧无际:@策马鞭程 给你发个链接,你看一下https://github.com/coolnameismy/BabyBluetooth/wiki/%E7%94%A8%E6%B3%95%E7%A4%BA%E4%BE%8B

      本文标题:使用BabyBluetooth进行蓝牙连接

      本文链接:https://www.haomeiwen.com/subject/mmjoettx.html