iOS 扫描周边的蓝牙4.0设备并实现连接

一引言

       最近在为下一个项目做准备, 其中有一项是手机跟蓝牙4.0的外设连接并实现通讯(非4.0的外设会很麻烦, 需要了解的可以自行的去查, 这里不再具体说).所有抽空简单学习了一下iOS中的coreBluetooth框架以及一些简单的应用, 由于我们的通讯已经有同事封装了现成的sdk, 这里不涉及通讯的内容(其实是我也不太清楚).就跟大家简单的说一下扫描和连接.

二.iOS蓝牙连接的解决方案

iOS设备蓝牙连接主要有一下几种实现方式:

①.参加苹果的(MFI)计划, 也就是需要得到苹果的认证, 费用高, 至于高到什么程度, 自己可以去查一下.

②.coreBluetooth框架. 只支持4.0的蓝牙设备, 也是本文的主角, 一会会具体说.

③.GameKit框架. 这个框架只用用于iOS设备之间的蓝牙连接通讯, 并不符合我们的需求, 没有仔细研究.

④.私有API(BluetoothManager框架). 这个东西怎么说, 对于一些经历过被拒的惨痛教训的人来说, 用私有api?还是算了吧, 如果你想用, 你可以试试,反正我是不用!

⑤.越狱. 如果你做越狱包得话,这个就随意了, 想怎么用怎么用.

三.coreBluetooth框架连接4.0的蓝牙外设

 CoreBluetooth两个很重要的概念,Central 和 Periperal Devices. 也就是中心和外设, 这里我们是要用手机扫描外设, 连接之后实现通讯, 所以这里我们的手机就是Central了.

首先, 我们创建一个工程, 导入coreBluetooth框架

然后就是在我们的项目中引入coreBluetooth框架了.这里封装了一个工具类, .h文件如下代码

#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>
#import <UIKit/UIKit.h>

/** 工具类
 * @note 用于扫描周边的蓝牙4.0设备,并存储
 */
@interface GetBluetoothEquipmentNearby : NSObject<CBCentralManagerDelegate>

/*...用于存储周边的设备列表...*/
@property (nonatomic, strong)NSMutableArray * devicesListArray;

/** 扫描周边外设
 * @note 扫描周边的所有蓝牙4.0外设
 */
-(void)discoverDevices;

 

以下是代码的实现部分了:

-(void)discoverDevices
{
    /*...创建manager对象, 创建完成之后会回调代理方法...*/
    self.bluetoothManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
    
    /*...扫描周边的外设...*/
    [self.bluetoothManager scanForPeripheralsWithServices:nil options:nil];
}

创建完之后, 会回调代理方法

- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
    switch ([central state])
    {
        case CBCentralManagerStateUnsupported:
            NSLog(@"蓝牙不可用");
            break;
        case CBCentralManagerStateUnauthorized:
            NSLog(@"未授权");
            break;
        case CBCentralManagerStatePoweredOff:
            NSLog(@"蓝牙未打开");
            break;
        case CBCentralManagerStatePoweredOn:
            NSLog(@"蓝牙已打开");
            break;
        case CBCentralManagerStateUnknown:
            NSLog(@"状态未知");
        default:
            NSLog(@"不明情况了");
            ;
    }
}

接着就是扫描外设了, 这里我们参数都传的是nil, 意思就是扫描所有的外设.当然你也可以传一个UUID进去, 是以数组的形式传得.这里由于我们做的是模拟第一次连接, 也就没有指定的UUID了, 有兴趣的可以自己测一下传一个UUID进去.

 /*...扫描周边的外设...*/
    [self.bluetoothManager scanForPeripheralsWithServices:nil options:nil];

这就开始扫描了外设, 扫描到外设的时候同样是会回调代理方法来通知我们的.

/*...扫描到外设的时候会调该方法...*/
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
    if(![self.devicesListArray containsObject:peripheral])
        [self.devicesListArray addObject:peripheral];
    
    NSLog(@"%@", peripheral.identifier);
    NSLog(@"%@", peripheral);
}

这里打印出来的peripheral.identifier就是外设的UUID, 以我的代码风格来说的话, 这个时候我会用个model来存储该外设的所有信息. 以后用的话也方便, 至于你想怎么用, 这个就因人而异了.另外还有注意的是,打印的一些其他参数advertisementData是广告数据,rssi代表着信号强度. 由于我这会并没有外设让我来测试, 我这边也没法贴图给大家了,见谅.

像苹果这样这么追求用户体验的,有开始扫描, 必定会有停止扫描了, 至于在什么时候停止, 这就看各位看官们的心情了.

[self.bluetoothManager stopScan];

 

下面就是连接了, 这里很方便:

//连接指定的设备
-(BOOL)connect:(CBPeripheral *)peripheral
{
    [self.bluetoothManager connectPeripheral:peripheral
                       options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey]];
    return YES;
}

这里连接到的设备是可以自己去指定的.显然以苹果的风格, 连接成功之后需要回调来通知我们连接成功的.

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
    NSLog(@"Did connect to peripheral: %@", peripheral);
}

到这里, 就实现了扫描蓝牙4.0的外设并实现连接了.至于加定时器来监控连接超时, 这个我想大家应该都会写, 这里不再贴代码.

四.结语

正如我开头说的, 我们的通讯有同事封装好的SDK, 所以这里就没有介绍扫描外设中的服务, 以及订阅这些内容了.只是单纯的一个扫描和连接, 如果你想让你的功能类更强大, 就可以根据需求填一些功能了, 比如监听连接状态, 连接超时, 自动重连等等.

 

另:我这边有一个问题一直没有解决, 就是:第一次用的时候, 跳到设置里面去把蓝牙打开之后, 我不知道怎么让他自动跳回到应用中, 害的我每次都要重新启动应用.这里希望知道怎么解决的朋友说一下, 不胜感激!--CP

posted on 2015-01-29 11:13  Now丶薄荷  阅读(6145)  评论(1编辑  收藏  举报

导航