做智能玩具、智能家居、智能穿戴已经将近3年了,期间各种坎坷,学习过好多种无线通信方式。但是因为换工作的原因,每个企业的无线通信方式都不一样(wifi、音频、蓝牙ble、蓝牙2.0),导致学习到了知识经常会忘记,想用的时候还要临时去捡回知识,经常忘记一些通信陷阱,每次重新捡回时都被坑一次,让人苦不堪言,所以我想这几天将上家公司的蓝牙ble通信纪录下来,注重的列出代码和讲解各种恶心的陷阱。废话不多说开始吧!
我不是科班出身,技术这些东西都是自己纠结出来的,不懂什么原理,比较喜欢直接上代码。大家都是搞技术的,这样比较好沟通。
BLEClass吧,首先我们在BLEClass.h导入<CoreBluetooth/CoreBluetooth.h>头文件,为什么我就不多说了,自己看头文件名字。同时定义一个对象名字叫CBCentralManager* manager,遮个对象是蓝牙管理中心,里面的api主要是用于搜索、连接等操作(大多数人都是做这几样操作、有特殊需求的可以自己看看,很容易看得懂的)。然后我们实现一下<CBCentralManagerDelegate>遮个代理(委托),从遮个的api中可以知道,我们必须要实现一个方法
centralManagerDidUpdateState ,遮个方法主要是用于当用户手动关闭设置中的蓝牙时,会回调这个代理方法(我平时都不用的,后续你们可以尝试一下效果,有答案了告诉我),这里有很多的api,我就用最有用的来说吧(特殊需求自己看api,问我也行)。
//初始化蓝牙中心
-(void)setup
{
managerCBCentralManageralloc] initWithDelegate:selfqueue:nil];
}
//搜索蓝牙(貌似BLE的蓝牙都能搜出来,这个不确定,反正我没试过搜不出来的)
//这里有个重点的:scanForPeripheralsWithServices:(这里可以填写目标蓝牙的ServicesUUID),填写后,苹果会帮你过滤掉其他uuid的蓝牙,只显示符合uuid的蓝牙ble
//栗子: [managerscanForPeripheralsWithServices:@[[CBUUIDUUIDWithString:@"0xFFF0"],[CBUUIDUUIDWithString:@"0x18F0"]]options:0];
-(void)findBluetooth
{
ifmanagerstate] != CBCentralManagerStatePoweredOn) {
printf("CoreBluetooth is not correctly initialized !\n");
return;
}
managerscanForPeripheralsWithServices:niloptions:0];
return;
}
//以上是搜索,但是搜索过程中我们需要接收和保存搜索到的蓝牙对象啊,所以我们需要new一个可变数组,回到.h中。定义一个可变数组,这里我们定义为peripherals。这个数组最好和蓝牙中心一起初始化。
//我们通过delegate找到了一个名字叫:- (void)centralManager:(CBCentralManagerCBPeripheralNSDictionaryNSNumber *)RSSI
//的方法,这个方法我们需要实现他,因为系统搜索到蓝牙后它会回调这个代理。
//代理参数分析:1.蓝牙中心对象 2.蓝牙对象 3.蓝牙广播包信息 4.信号强弱
- (void)centralManager:(CBCentralManagerCBPeripheralNSDictionaryNSNumber *)RSSI{
//这里主要是判断和保存蓝牙对象
//判断主要为了防止重复搜索出同一个蓝牙对象,所以我们需要用强化for循环来循环判断
return;
forCBPeripheralinperipherals) {
ifidentifierisEqual:p.identifier]) {
return;
}
}
peripheralsaddObject:peripheral];
//这里是本类的代理,主要用于将蓝牙传递给需要的类
//怎么去写delegate这个就不多说了
ifdelegaterespondsToSelector:@selector(foundNewBluetooth:)]) {
[delegate foundNewBluetooth:peripheral];
}
}
//目前我们已经搜索到了蓝牙对象,同时也保存好了,那么下一步我们需要的是如何去连接
//其实连接蓝牙还是比较简单的,因为苹果api已经提供了对应接口,我门只需要传参就好
//这里我写的是一个接口,主要给其他类去调用
//从方法所需要的参数我门可以知道,连接蓝牙需要一个蓝牙对,也就是我门刚刚搜索到的蓝牙对象中的一个(你想连接哪个,就将他传进来)
//建议定义一个当前连接的蓝牙的对象属性,也就是CBPeripheral *currentBluetooth
-(void)connect:(CBPeripheral *)peripheral
{
ifisConnected]) {
managerconnectPeripheral:peripheral options:nil];
}
}
//这里是一个断开蓝牙的api接口,同时也需要将当前连接的蓝牙对象传入即可断开
-(void)disConnect:(CBPeripheral *)peripheral
{
managercancelPeripheralConnection:peripheral];
}