iOS蓝牙开发

作者: TianBai | 来源:发表于2016-05-30 22:51 被阅读13759次

    iOS的蓝牙数据接收以及发送

    1. 名词:Central(中心设备)、Peripheral(外围设备)、advertising(广告)、Services(服务)、Characteristic(特征)
    2. 新建Central Manager实例进行蓝牙管理
    3. 搜索外围设备
    4. 连接外围设备
    5. 获得外围设备的服务
    6. 获得服务的特征
    7. 给外围设备发送数据
    8. 从外围设备读数据

    蓝牙介绍

    本文要介绍的CoreBluetooth,专门用于与BLE设备通讯。并且现在很多蓝牙设备都支持4.0,4.0以其低功耗著称,所以一般也叫BLE(Bluetoothlow energy),所以也是在iOS比较推荐的一种开发方法。

    CoreBluetooth介绍

    在CoreBluetooth中有两个主要的部分,Central和Peripheral,CBPeripheralManager 作为周边设备。CBCentralManager作为中心设备。所有可用的iOS设备可以作为周边(Peripheral)也可以作为中央(Central),但不可以同时既是周边也是中央。

    1. 周边设备(Peripheral)设备是广播设备的数据,中央设备(Central)是管理并且使用这些数据的设备。
    2. 也就是说周边(Peripheral)向周围发送广播,告诉周围的中央设备(Central)它(周边(Peripheral)这里有数据,并且说明了能提供的服务和特征值(连接之后才能获取),
    3. 其实蓝牙传值相当于网络接口,硬件的service的UUID加上characteristic的UUID,
      打一个比喻:service的UUID相当于主地址,characteristic的UUID相当于短链接,短链接必须是主地址的分支,拼在一起的是接口,你和硬件设定的蓝牙传输格式类似于json,双方可识别的数据,因为蓝牙只能支持16进制,而且每次传输只能20个字节,所以要把信息流转成双方可识别的16进制

    实现方法介绍

    • .h 导入头文件
    #import <CoreBluetooth/CoreBluetooth.h>
    
    • 自定义设置枚举状态
    
    typedef NS_ENUM(NSInteger, BluetoothState){
        BluetoothStateDisconnect = 0,
        BluetoothStateScanSuccess,
        BluetoothStateScaning,
        BluetoothStateConnected,
        BluetoothStateConnecting
    };
    
    typedef NS_ENUM(NSInteger, BluetoothFailState){
        BluetoothFailStateUnExit = 0,
        BluetoothFailStateUnKnow,
        BluetoothFailStateByHW,
        BluetoothFailStateByOff,
        BluetoothFailStateUnauthorized,
        BluetoothFailStateByTimeout
    };
    
    
    • 设置代理
    <CBCentralManagerDelegate,CBPeripheralDelegate>
    
    • 添加属性
    @property (strong , nonatomic) UITableView *tableView;
    @property (strong , nonatomic) CBCentralManager *manager;//中央设备
    @property (assign , nonatomic) BluetoothFailState bluetoothFailState;
    @property (assign , nonatomic) BluetoothState bluetoothState;
    @property (strong , nonatomic) CBPeripheral * discoveredPeripheral;//周边设备
    @property (strong , nonatomic) CBCharacteristic *characteristic1;//周边设备服务特性
    @property (strong , nonatomic) NSMutableArray *BleViewPerArr;
    
    • 创建UITableView
    -(void)setTableView{
        _tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 20, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height) style:UITableViewStyleGrouped];
        _tableView.delegate = self;
        _tableView.dataSource = self;
        _tableView.backgroundColor = [UIColor whiteColor];
        [self.view addSubview:_tableView];
    }
    
    • 接下来写tableView的dalegate
    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"IsConnect"];
        if (cell == nil) {
            cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"IsConnect"];
        }
        
        // 将蓝牙外设对象接出,取出name,显示
        //蓝牙对象在下面环节会查找出来,被放进BleViewPerArr数组里面,是CBPeripheral对象
        CBPeripheral *per=(CBPeripheral *)_BleViewPerArr[indexPath.row];
        NSString *bleName=[per.name substringWithRange:NSMakeRange(0, 9)];
        cell.textLabel.text = per.name;
        return cell;
    }
    
    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
        return 44;
    }
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
        return _BleViewPerArr.count;
    }
    
    
    • 创建实例,设置代理,创建数组管理外设,
    self.manager = [[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_main_queue()];
    self.manager.delegate = self;
    self.BleViewPerArr = [[NSMutableArray alloc]initWithCapacity:1];
    
    
    • 开始扫描
    -(void)scan{
        //判断状态开始扫瞄周围设备 第一个参数为空则会扫瞄所有的可连接设备  你可以
        //指定一个CBUUID对象 从而只扫瞄注册用指定服务的设备
        //scanForPeripheralsWithServices方法调用完后会调用代理CBCentralManagerDelegate的
        //- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI方法
        [self.manager scanForPeripheralsWithServices:nil options:@{ CBCentralManagerScanOptionAllowDuplicatesKey : @NO }];
        //记录目前是扫描状态
        _bluetoothState = BluetoothStateScaning;
        //清空所有外设数组
        [self.BleViewPerArr removeAllObjects];
        //如果蓝牙状态未开启,提示开启蓝牙
        if(_bluetoothFailState==BluetoothFailStateByOff)
        {
            NSLog(@"%@",@"检查您的蓝牙是否开启后重试");
        }
    
    }
    
    • 接下来会检测蓝牙状态
    - (void)centralManagerDidUpdateState:(CBCentralManager *)central
    {
        if (central.state != CBCentralManagerStatePoweredOn) {
            NSLog(@"fail, state is off.");
            switch (central.state) {
                case CBCentralManagerStatePoweredOff:
                    NSLog(@"连接失败了\n请您再检查一下您的手机蓝牙是否开启,\n然后再试一次吧");
                    _bluetoothFailState = BluetoothFailStateByOff;
                    break;
                case CBCentralManagerStateResetting:
                    _bluetoothFailState=BluetoothFailStateByTimeout;
                    break;
                case CBCentralManagerStateUnsupported:
                    NSLog(@"检测到您的手机不支持蓝牙4.0\n所以建立不了连接.建议更换您\n的手机再试试。");
                    _bluetoothFailState = BluetoothFailStateByHW;
                    break;
                case CBCentralManagerStateUnauthorized:
                    NSLog(@"连接失败了\n请您再检查一下您的手机蓝牙是否开启,\n然后再试一次吧");
                    _bluetoothFailState = BluetoothFailStateUnauthorized;
                    break;
                case CBCentralManagerStateUnknown:
                    _bluetoothFailState = BluetoothFailStateUnKnow;
                    break;
                default:
                    break;
            }
            return;
        }
        _bluetoothFailState = BluetoothFailStateUnExit;
        // ... so start scanning
    }
    
    
    • 中央设备开始扫描之后,我们需要实现 centralManager:didDiscoverPeripheral:advertisementData:RSSI: 通过该回调来获取发现设备。
      这个回调说明着广播数据和信号质量(RSSI-Received Signal Strength Indicator)的周边设备被发现。通过信号质量,可以用判断周边设备离中央设备的远近。
    - (void)centralManager:(CBCentralManager *)central
     didDiscoverPeripheral:(CBPeripheral *)peripheral
         advertisementData:(NSDictionary *)advertisementData
                      RSSI:(NSNumber *)RSSI
    {
        if (peripheral == nil||peripheral.identifier == nil/*||peripheral.name == nil*/)
        {
            return;
        }
        NSString *pername=[NSString stringWithFormat:@"%@",peripheral.name];
        //判断是否存在@"你的设备名"
        NSRange range=[pername rangeOfString:@"你的设备名"];
        //如果从搜索到的设备中找到指定设备名,和BleViewPerArr数组没有它的地址
        //加入BleViewPerArr数组
        if(range.location!=NSNotFound&&[_BleViewPerArr containsObject:peripheral]==NO){
            [_BleViewPerArr addObject:peripheral];
        }
        _bluetoothFailState = BluetoothFailStateUnExit;
        _bluetoothState = BluetoothStateScanSuccess;
        [_tableView reloadData];
    }
    

    扫描设备输出台log:

    <CBPeripheral: 0x14e625f80, identifier = 954DBF72-104A-E041-19F8-D9538DBA7C23, name = brand, state = disconnected>
    

    蓝牙广播中可以携带一些信息,最好将mac 地址也一并在这里广播出来!!!
    扫描设备advertisementData 输出台log :

    Printing description of advertisementData:
    {
        kCBAdvDataIsConnectable = 1;
        kCBAdvDataLocalName = "brand";
        kCBAdvDataTxPowerLevel = 2;
    }
    
    • 扫描到设备之后当然是链接设备了,这里会有一个UITableView,在tableview点击方法里写连接方法
    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
        CBPeripheral *peripheral=(CBPeripheral *)_BleViewPerArr[indexPath.row];
        //设定周边设备,指定代理者
        _discoveredPeripheral = peripheral;
        _discoveredPeripheral.delegate = self;
        //连接设备
        [_manager connectPeripheral:peripheral
                            options:@{CBConnectPeripheralOptionNotifyOnConnectionKey:@YES}];
    }
    
    

    说明 : 点击单元格连接对应的设备,连接该设备 调用完该方法后会调用代理- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral表示连接上了设备

    连接失败会调用- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error

    • 已经连接上该设备,就可以获取当前设备的信息
    // 获取当前设备
    - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
    {
        NSLog(@"%@",peripheral);
        
        // 设置设备代理
        [peripheral setDelegate:self];
        // 大概获取服务和特征
        [peripheral discoverServices:nil];
        
        //或许只获取你的设备蓝牙服务的uuid数组,一个或者多个
        //[peripheral discoverServices:@[[CBUUID UUIDWithString:@""],[CBUUID UUIDWithString:@""]]];
        
        
        NSLog(@"Peripheral Connected");
        
        [_manager stopScan];
        
        NSLog(@"Scanning stopped");
        
        _bluetoothState=BluetoothStateConnected;
        
    }
    
    
    • 各种服务

    说明:在这个方法中我们要查找到我们需要的服务 然后调用discoverCharacteristics方法查找我们需要的特性
    该discoverCharacteristics方法调用完后会调用代理CBPeripheralDelegate的- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error

    // 获取当前设备服务services
    - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
    {
        if (error) {
            NSLog(@"Error discovering services: %@", [error localizedDescription]);
            return;
        }
        
        NSLog(@"所有的servicesUUID%@",peripheral.services);
    
        //遍历所有service
        for (CBService *service in peripheral.services)
        {
            
            NSLog(@"服务%@",service.UUID);
            
            //找到你需要的servicesuuid
            if ([service.UUID isEqual:[CBUUID UUIDWithString:@"你的设备服务的uuid"]])
            {
                //监听它
                [peripheral discoverCharacteristics:nil forService:service];
            }
            
            
            
        }
        NSLog(@"此时链接的peripheral:%@",peripheral);
        
    }
    
    
    • 特征获取

    说明:在这个方法中我们要找到我们所需的服务的特性 然后调用setNotifyValue方法告知我们要监测这个服务特性的状态变化 当setNotifyValue方法调用后调用代理CBPeripheralDelegate的- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error

    - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
    {
        
        if (error)
        {
            NSLog(@"Discovered characteristics for %@ with error: %@", service.UUID, [error localizedDescription]);
            return;
        }
        NSLog(@"服务:%@",service.UUID);
        // 特征
        for (CBCharacteristic *characteristic in service.characteristics)
        {
            NSLog(@"%@",characteristic.UUID);
            //发现特征
            //注意:uuid 分为可读,可写,要区别对待!!!
            
            
            if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"你的特征uuid"]])
            {
                NSLog(@"监听:%@",characteristic);//监听特征
                //保存characteristic特征值对象
                //以后发信息也是用这个uuid
                _characteristic1 = characteristic;
                
                [_discoveredPeripheral setNotifyValue:YES forCharacteristic:characteristic];
            }
            
            //当然,你也可以监听多个characteristic特征值对象
            if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"你的特征uuid"]])
            {
                //同样用一个变量保存,demo里面没有声明变量,要去声明
    //            _characteristic2 = characteristic;
    //            [peripheral setNotifyValue:YES forCharacteristic:_characteristic2];
    //            NSLog(@"监听:%@",characteristic);//监听特征
            }
        }
    }
    
    
    - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
    {
        if (error)
        {
            NSLog(@"Error updating value for characteristic %@ error: %@", characteristic.UUID, [error localizedDescription]);
            return;
        }
        
        NSLog(@"收到的数据:%@",characteristic.value);
    }
    

    蓝牙传值

    蓝牙写到这里,基本用法已经说明,代码千变万变,思路不变,接下来介绍传值,因为我的项目是手环,我就以我们硬件工程师的蓝牙接口文档来介绍如何和硬件交互,
    其实蓝牙传值相当于网络接口,硬件的service的UUID加上characteristic的UUID,
    打一个比喻:service的UUID相当于主地址,characteristic的UUID相当于短链接,短链接必须是主地址的分支,拼在一起的是接口,你和硬件设定的蓝牙传输格式类似于json,双方可识别的数据,因为蓝牙只能支持16进制,而且每次传输只能20个字节,所以要把信息流转成双方可识别的16进制

    1. 下面是手环的接口文档

    APP请求运动模式基础数据传输时拆分的总包数

    字节序号 参数值
    0 0xa5
    1 0x06
    2 0x03
    3~4 2字节的时间,如1月2日用0x0102表示。
    5 异或校验和

    由此看出:0、1、2字节都是固定的,3字节是月(16进制),4字节是日(16进制),5字节是异或校验和

    那么:

    // APP请求运动模式基础数据传输时拆分的总包数
    - (NSData *)sportBao
    {
        Byte reg[6];
        reg[0]=0xa5;
        reg[1]=0x06;
        reg[2]=0x03;
        reg[3]=0x01;
        reg[4]=0x02;
        reg[5]=(Byte)(reg[0]^reg[1]^reg[2]^reg[3]^reg[4]);
        NSData *data=[NSData dataWithBytes:reg length:6];
        return data;
    }
    
    

    这时候,要把请求命令发送给手环,发送给刚才纪录的discoveredPeripheral的蓝牙设备的characteristic1的特征值

    // 获取总包数
    - (void)getAltogether
    {
    
        //生成总包数data
        NSData *d1 = [self sportBao];
        NSLog(@"写%@",d1);
        NSLog(@"%@",discoveredPeripheral);
      [discoveredPeripheral writeValue:d1 forCharacteristic:characteristic1 type:CBCharacteristicWriteWithResponse];
      
    }
      
    

    发送完成,手环会返回数据
    数据是以下格式:

    手环返回运动模式基础数据传输时拆分的总包数

    字节序号 参数值
    0 0xa5
    1 0x06
    2 0x83
    3~4 该运动模式数据传输时拆分的总包数
    5 异或校验和

    由此看出:0、1、2字节都是固定的,3-4字节是总包数(16进制),5字节是异或校验和

    那么:我们需要转换3-4字节的16进制,得到总包数

    - (void)SetAltogether:(NSData *)DayData
    {
        Byte *testByte = (Byte *)[DayData bytes];
        if (DayData.length == 6) {
            //收到数据之后,要异或校验,看数据是否完整以及正确
            if (testByte[5]==(testByte[0]^testByte[1]^testByte[2]^testByte[3]^testByte[4]))
            {
                // 这里记录总包数
                int totalBao = 0;
                totalBao = testByte[4]*256+testByte[3];
            }
        }
    }
    

    解析数据的格式已经有了,那么在接收数据的时候

    - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
        if (error)
        {
            NSLog(@"读失败");
            
            return;
        }
        NSLog(@"收到的数据 :%@",characteristic.value);
    
        NSString *str = [NSString stringWithFormat:@"%@",characteristic.value];
        
        
        // 运动总包数
        if (str.length>7&&[[str substringWithRange:NSMakeRange(1, 2)]isEqualToString:@"a5"]&&[[str substringWithRange:NSMakeRange(5, 2)]isEqualToString:@"83"]) {
            //调用解析总包数方法
            [self SetAltogether:characteristic.value];
    
        }
        
    }
    

    数据传输介绍完毕,基本用法已经说明

    相关文章

      网友评论

      • d428c82fffac:我开了蓝牙手机都连接上了,但是项目里提示蓝牙没开
      • 万事皆允_iOS:您,请问一下,为什么我只能搜到我周围的iphone和iMac 而我的蓝牙耳机却收不到呢?
      • NapoleonY:试了下,搜索不到android设备
      • 神一样的男人卫:楼主有demo吗?
      • 代码粉刷匠:大哥,给个Demo学习一下吧,我的邮箱22900662@qq.com,谢谢
      • a2f037f7bfbb:方法 didUpdateNotificationStateForCharacteristic:error 报以下错误
        Error Domain=CBATTErrorDomain Code=6 "The request is not supported." UserInfo={NSLocalizedDescription=The request is not supported.
        请问楼主知道怎么解决吗?谢谢
        TianBai:@itsLUO 好像是特征值不对吧
      • flycy:我最近在写一个蓝牙解锁的单车。。很懵逼 楼主能否指教下小白
      • graliet:请问 totalBao = testByte[4]*256+testByte[3]; 这句话是什么意思
      • 帝默:我有时候会一直连接中,失败成功方法都不走,这可能是是什么原因?
      • MN的奇遇:<CBCentralManager: 0x174478440> can only accept this command while in the powered on state 咋去结局啊 求帮助
      • MN的奇遇:大神 can only accept this command while in the powered on state 这个是什么问题了
        求大神解答一下

      • 伦敦乡下的小作家:谢谢楼主,是否能提供一下demo呀,小白不胜感激。
      • 415242e789ca:hi,大神,在做蓝牙,遇到一些问题能帮忙看下吗 ,谢谢 qq 1071872574
      • 伦敦乡下的小作家:楼主,可不可以分享一下完整的demo
      • 723519e7f1b1:弱弱的问一句,我用分段发送多个数据然后用通知读取value 时会出现重复的数据,我发10次数据,会的10次里面可能有一两次是相同的数据,用串口助手抓数据发送给我的10次都是不同的数据这是怎么回事呢?
        723519e7f1b1:我发数据是分段发送的,第一段数据发过去,然后读取,根据读取到的数据决定后面发几次数据,,我要保存后面读取的数据,改怎么保存?大概有500多字节,我每次读取56字节
        723519e7f1b1:我发过过去的10次数据没有问题,蓝牙那边返回得数据没问问题
        TianBai:@落幕星辰 硬件工程师给你反馈他收到的是什么?
      • 18bf637b25cd:楼主有没有demo 给个链接
      • shLuckySeven:您好,我现在在开发蓝牙,有个功能是密码配对,需求是密码配对不弹出那个配对提示框,app自己默默验证,让用户无感知,可以脚下不?谢谢
      • Zz7777777:有Demo吗
      • 夜间寻路人:楼主不知道你有没有遇到过。一次发送多个包,设备侧会收不到数据的情况吗?

        比如:一个包20字节,连续需要发送1000字节的数据,就有50个包,这样连续在一个for循环里面发送给设备,设备那边收到的数据就会有异常。必须我们这边控制,发了25个包后,睡眠500毫秒,再继续发才行。
      • STONEsh:你好,输出的identifier代表的是serviceUUID吗?
      • STONEsh:楼主能不能给发一下DEMO,非常需要,谢谢了.510508772@qq.com
      • Newquine:楼主,如果要修改外设蓝牙的名称,怎么实现? 非常感谢
        TianBai:两种方法
        1 链接之后,把改的名字发送给硬件,硬件下次广播就用新的名字
        2 保存到本地,下次找到这个设备,直接显示已经更改过的名字
      • 2ff2f41ed69e:你好 我是蓝牙新手 可以加一个好友吗 问一个问题 :smile:
      • 达若漠沙:楼主,请问一下,如果蓝牙传输的数据大于20字节,在读取蓝牙数据的时候,该如何解析呢~~可以给下思路不~~感谢
        达若漠沙:恩,之前一直在纠结不知道一次发了多少包,不知道结束位,和硬件重新定义格式后,就按照指定字段获取包数,在拼接:+1::pray:
        TianBai:硬件发送的时候以20字节为一包,包里面最好有包序号,以防止丢包。
        解析的话,看你是要分包解析还是拼接起来一起解析了。都是可以的
      • L不来我不走:楼主能发个DEMO吗,自己写了下没能成功。m17186781705@163.com
      • 南方小金豆:如果周边有多个设备,怎么去连接离的最近的一个设备?
        Rick_:不同设备信号强度不能判断距离的远近吧?
        把你的天空染成淡蓝色:可以通过信号强度去判断距离的远近
        Silenceapple:这个需求牛逼了
      • 小杂鱼:机油肥皂群 前来膜拜大神
      • 9449ac8cc6ba:项目在赶 看见了 希望快速回复我,谢谢
      • 9449ac8cc6ba:您好,我刚接触蓝牙,有些问题请教您。172158320
      • 流年里不舍的温柔:没事去csdn吧,
      • 秋天的橘子:大神,看不懂。不理解。以前没接触过程序,硬着头皮进门的。现在做蓝牙,我只能实现连接蓝牙,文档那些看不懂,能不能教一教我。Q631487050!!!请教了!
        TianBai:@秋天的橘子 嗯
      • leftwater:666666
      • 抹茶不加糖:请问蓝牙的major,,在哪个回调方法里面可以得到?
        宁哈哈哈:@抹茶不加糖 CoreLocation
      • Scorpio_糖果屋:楼主大神,我在didUpdateValueForCharacteristic这个方法里面读取到characteristic.value的值,怎样把它转成10进制的数
        QDboys:@Scorpio_糖果屋 按照你这代码打印出来的就是10进制的数
        Scorpio_糖果屋:@QDboys
        NSData *data = characteristic.value;
        Byte *testByte = (Byte *)[data bytes];
        for (int i = 0; i < [data length]; i++) {
        NSLog(@"testByte:%d",testByte[i]);
        }
        我是用上面的方法转,原本value的值是<ef490021>转了之后就变成23 87 30 33,这是16进制的,还要继续转10进制的,不知是不是我方法不正确,楼主知道吗
        QDboys:@Scorpio_糖果屋 转成字节数组打印出来不就是10进制么
      • 7f4097b47ca3:哇⊙ω⊙好腻害哦
      • 醉春风:学习啦!!好东西!!顶!!
      • 613d0b93135c: 虽说现在用不到 但我感觉是好东西 以后肯定得看
        TianBai:@包子btw :kissing_heart::kissing_heart::kissing_heart:
      • 香烟不灭:我完全按照你写的,写了一遍。但是不走centralManager:didDiscoverPeripheral:advertisementData:RSSI: 该回调方法。
        gaoyinhui:@香烟不灭 我也是不走centralManager:didDiscoverPeripheral:advertisementData:RSSI这个方法 代理设置了 蓝牙设备 周边人的手机算吗?
        香烟不灭:@TianBai 嗯,弄好了!挺受用的,谢谢!
        TianBai:@香烟不灭 看下代理设置了吗?周边是否有蓝牙设备

      本文标题:iOS蓝牙开发

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