说明:这次实践的主要目的是简单掌握蓝牙的一些基本信息,实现数据的接发,中心与外设互相发送数据,大数据分块发送。最后为项目链接。
蓝牙基础(常见缩写)
MFI: 专们为苹果设备制作的设备,详见:关于MFi认证你所必须要知道的事情;
BLE:蓝牙4.0设备因为低耗电,所以也叫做BLE;
MFI:开发使用ExternalAccessory 框架;
4.0 BLE:开发使用CoreBluetooth 框架;
Peripheral:外设,被连接的设备为Peripheral;
Central:中心,发起连接的是Central;
Service:服务,每个外设会有很多服务,每个服务中包含很多字段,这些字段的权限一般分为 读read,写write,通知notiy几种;
Characteristic:一个服务下面也可以存在多个特征,特征可以理解成具体实现功能的窗口,一般特征都会有value,也就是特征值,特征是与外界交互的最小单位;
Description:每个特征可以对应一个或多个Description用户描述characteristic的信息或属性;
UUID:可以理解成蓝牙上的唯一标识符,为了区分不同的服务和特征,或者给服务和特征取名字,我们就用UUID来代表服务和特征;
快速生成UUID:
打开Mac OS X的Terminal.app,用uuidgen命令生成一个128bit的UUID
//服务id
#define TRANSFER_SERVICE_UUID @"0FB51F75-C9D5-45DC-BA61-065BD4A5E3E8"
//特征id
#define TRANSFER_CHARACTERISTIC_UP_UUID @"B678C8E2-9B1A-4952-A320-EF6D42F0831A"
-------------------------------
蓝牙中心模式流程:
1. 建立中心角色
2. 扫描外设(discover)
3. 连接外设(connect)
4. 扫描外设中的服务和特征(discover)
5. 与外设做数据交互(explore and interact)
6. 订阅Characteristic的通知
7. 断开连接(disconnect)
中心:首先要导入蓝牙库
#import
遵守协议
1. 建立中心角色 创建CBCentralManager对象
_centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
2. 扫描外设(discover)
//查看设备是否支持 ,若支持则扫描
-(void)centralManagerDidUpdateState:(CBCentralManager *)central{
NSArray *uuidArray = [NSArray arrayWithObjects:[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID],nil];
NSDictionary *optionsDic = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithBool:NO],CBCentralManagerScanOptionAllowDuplicatesKey, nil];
[_centralManager scanForPeripheralsWithServices:uuidArray options:optionsDic];
}
3. 连接外设(connect)
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
if (_discoveredPeripheral != peripheral) {
_discoveredPeripheral = peripheral;
[_centralManager connectPeripheral:peripheral options:nil];
}
}
4. 扫描外设中的服务和特征(discover)
//当连接成功后,系统会通过回调函数告诉我们,然后我们就在这个回调里去扫描设备下所有的服务和特征
-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
peripheral.delegate = self;
//指定服务
[peripheral discoverServices:[[NSArray alloc] initWithObjects:[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID], nil]];
//[peripheral discoverServices:nil];
}
-4.1 获取外设的services 6. 订阅Characteristic的通知
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
//处理我们需要的特征
for (int i=0; i
外设:首先要导入蓝牙库
#import
遵守协议
1. 建立外设角色 创建CBPeripheralManager对象
_peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil];
2. 本地Peripheral设置服务,特性,描述,权限等等
//1 查看设备是否支持 ,若支持则创建 服务和特征
-(void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral{
//一组特征值
_upCharacteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_UP_UUID] properties:CBCharacteristicPropertyNotify | CBCharacteristicPropertyRead | CBCharacteristicPropertyWrite | CBCharacteristicPropertyWriteWithoutResponse value:nil permissions:CBAttributePermissionsReadable | CBAttributePermissionsWriteable];
//一个服务中添加多个特征值
transferService = [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID] primary:YES];
NSArray *characters = [[NSArray alloc] initWithObjects:_upCharacteristic, nil];
[transferService setCharacteristics:characters];
// 2 添加一个服务
[self.peripheralManager addService:transferService];
}
3. Peripheral发送广告
// 3 会监听didAddService
-(void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error{
NSLog(@"添加服务");
if (error != nil) {
NSLog(@"添加服务失败: %@",error.localizedDescription);
} else {
// 开始广播
[self.peripheralManager startAdvertising:@{ CBAdvertisementDataLocalNameKey : @"Service_name", CBAdvertisementDataServiceUUIDsKey :@[[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]] }];
}
}
4. 设置处理订阅、取消订阅、
//当中央端连接上了此设备并订阅了特征时会回调 didSubscribeToCharacteristic
-(void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic {
NSLog(@"中心已经预定了特征 --- %@",characteristic);
}
//当中央端取消订阅时会调用didUnsubscribeFromCharacteristic
-(void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic {
NSLog(@"中心没有从特征预定 -- %@",characteristic);
}
4. 读characteristic、写characteristic的委托方法
//当接收到中央端读的请求时会调用didReceiveReadRequest
- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request {
if (request.characteristic.properties & CBCharacteristicPropertyRead) {
NSData *data = request.characteristic.value;
[request setValue:data];
[self.peripheralManager respondToRequest:request withResult:CBATTErrorSuccess];
} else {
[self.peripheralManager respondToRequest:request withResult:CBATTErrorReadNotPermitted];
}
}
//当接收到中央端写的请求时会调用didReceiveWriteRequest
- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray *)requests {
CBATTRequest *request = requests[0];
if (request.characteristic.properties & CBCharacteristicPropertyWrite) {
CBMutableCharacteristic *c = (CBMutableCharacteristic *)request.characteristic;
c.value = request.value;
NSData *data = c.value;
[self.peripheralManager respondToRequest:request withResult:CBATTErrorSuccess];
} else {
[self.peripheralManager respondToRequest:request withResult:CBATTErrorWriteNotPermitted];
}
}
4. 往中心发送数据
- (BOOL)updateValue:(NSData *)value characteristic:(CBMutableCharacteristic *)characteristic {
if (value && characteristic) {
return [self.peripheralManager updateValue:value forCharacteristic:characteristic onSubscribedCentrals:nil];
}
return NO;
}
项目Demo:蓝牙外设 、蓝牙中心