前言:此篇文章只针对第一次接触蓝牙的小白,文章中仅仅描述了如何连接蓝牙、如何发送数据 、可能遇到的问题 等。对于其他专业性的名词没有做相应的描述。
一、准备工作
1、iOS使用蓝牙 必须先允许定位,所以需要开启定位。使用蓝牙需要用户同意才可使用 所以 工程info.plist 文件中需要添加 定位请求和蓝牙请求的权限
定位权限
Privacy - Location When In Use Usage Description
蓝牙权限
Privacy - Bluetooth Peripheral Usage Description
2、使用蓝牙首先要准备几个UUID
服务UUID
#define BLE_SERVICE_UUID @"0000XXXX-0000-1000-8000-00805f9b34fb"
读UUID
#define BLE_INDICATE_CHARACTERISTIC_UUID @"0000XXXX-0000-1000-8000-00805f9b34fb"
写UUID
#define BLE_WRITE_CHARACTERISTIC_UUID @"0000XXXX-0000-1000-8000-00805f9b34fb"
这几个UUID开发硬件的工程师会直接给你。作用后面会有所体验
二、设置相关代码
1、首先引入蓝牙和定位所需框架
#import <SystemConfiguration/CaptiveNetwork.h>
#import <CoreLocation/CoreLocation.h>
#import <CoreBluetooth/CoreBluetooth.h>
2、其次引入代理
CBCentralManagerDelegate
CBPeripheralDelegate
3、然后声明属性
@property (nonatomic, strong) CBCentralManager * bluetoothManager;
@property (nonatomic, strong) CLLocationManager * locationManager;
@property (nonatomic, strong) CBPeripheral * currentPer;
4、设置定位
- (void)location {
NSString* phoneVersion = [[UIDevice currentDevice] systemVersion];
CGFloat version = [phoneVersion floatValue];
// 如果是iOS13 未开启地理位置权限 需要提示一下
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined && version >= 13) {
self.locationManager = [[CLLocationManager alloc] init];
[self.locationManager requestWhenInUseAuthorization];
}
}
重点来了,以下代码是蓝牙相关的代码
1、初始化 CBCentralManager
#pragma mark-- CBCentralManager的实例对象
- (void)initCBCentralManager{
NSDictionary *options = @{CBCentralManagerOptionShowPowerAlertKey: @YES};
CBCentralManager* cBCentralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:options];
self.bluetoothManager = cBCentralManager;
}
2、 CBCentralManagerDelegate回调:返回蓝牙的状态 在此函数中可以提醒用户打开蓝牙等操作
#pragma mark-- CBCentralManagerDelegate回调:(开启/关闭蓝牙,也就是蓝牙的状态)
- (void)centralManagerDidUpdateState:(CBCentralManager*)central{
if (central.state == CBCentralManagerStatePoweredOn) {
NSLog(@"蓝牙已经打开");
} else if (central.state == CBManagerStatePoweredOff) {
NSLog(@"蓝牙已经关闭");
}
}
3、开始扫描蓝牙设备
#pragma mark-- 开始扫描设备(也就是开始扫描蓝牙)
- (void)scanDevice{
[self.bluetoothManager scanForPeripheralsWithServices:nil options:nil];
}
4、蓝牙设备扫描结果回调:在此方法中找到你想要连接的蓝牙设备然后去连接设备
#pragma mark-- CBCentralManagerDelegate回调:蓝牙搜索结果回调
- (void)centralManager:(CBCentralManager*)central didDiscoverPeripheral:(CBPeripheral*)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber*)RSSI{
NSString *scanedName=advertisementData[@"kCBAdvDataLocalName"];
if (scanedName.length>0) {
NSLog(@"扫描到设备scanedName=:%@",scanedName);
}
if ([scanedName hasPrefix:@"aux-5802"]) {
self.currentPer = peripheral;
// 发现设备后,请求连接设备
[self connectedDevices];
}
}
#pragma mark-- 开始连接设备:
- (void)connectedDevices{
[self.bluetoothManager connectPeripheral:self.currentPer options:nil];
}
5、连接状态回调
#pragma mark-- 链接状态回调
///连接成功
- (void)centralManager:(CBCentralManager*)central didConnectPeripheral:(CBPeripheral*)peripheral{
NSLog(@"连接成功");
//连接成功停止搜索
[self.bluetoothManager stopScan];
self.currentPer = peripheral;
//连接成功后,扫描外围设备的服务CBService:
[self scanDeviceCBService];
}
///连接失败
- (void)centralManager:(CBCentralManager*)central didFailToConnectPeripheral:(CBPeripheral*)peripheral error:(NSError*)error{
NSLog(@"连接失败---%@",error);
}
///断开连接结果
- (void)centralManager:(CBCentralManager*)central didDisconnectPeripheral:(CBPeripheral*)peripheral error:(NSError*)error{
NSLog(@"断开链接");
}
#pragma mark-- 连接成功后,扫描外围设备的服务CBService:
- (void)scanDeviceCBService{
self.currentPer.delegate = self;
[ self.currentPer discoverServices:@[[CBUUID UUIDWithString:BLE_SERVICE_UUID]]];
}
6、 扫描服务结果会通过CBPeripheralDelegate回调 返回
#pragma mark-- 扫描服务结果会通过CBPeripheralDelegate回调:
- (void)peripheral:(CBPeripheral*)peripheral didDiscoverServices:(NSError*)error{
for (CBService *service in peripheral.services) {
if ([service.UUID isEqual:[CBUUID UUIDWithString:BLE_SERVICE_UUID]]) {
//查找特征
[self.currentPer discoverCharacteristics:nil forService:service];
}
}
}
7、查询特征结果会通过CBPeripheralDelegate回调:返回
#pragma mark--查询特征结果会通过CBPeripheralDelegate回调:
-(void)peripheral:(CBPeripheral*)peripheral didDiscoverCharacteristicsForService:(CBService*)service error:(NSError*)error{
for (CBCharacteristic *character in service.characteristics) {
NSLog(@"%@",character);
if ([character.UUID isEqual:[CBUUID UUIDWithString:BLE_WRITE_CHARACTERISTIC_UUID]]) {
// 写
//注意:1、这里的 writeValue: 传的是一个NSData类型的数据 这个数据硬件需要什么 你传什么就可以了。
//注意:2、这里的 type :你需要查看硬件给你返回的什么类型然后你填什么类型就可以了,这个类型可以打印 character 查看他的 properties属性 如果硬件返回的是 0x04(CBCharacteristicPropertyWriteWithoutResponse) 那你就需要填写对应的(CBCharacteristicWriteWithoutResponse)即可,切记这一点 否则会报 读或写没有权限的 问题
[self.currentPer writeValue: data forCharacteristic:character type:CBCharacteristicWriteWithoutResponse];
}else if ([character.UUID isEqual:[CBUUID UUIDWithString:BLE_INDICATE_CHARACTERISTIC_UUID]]) {
// 读
[self.currentPer setNotifyValue:YES forCharacteristic:character];
}
}
}
8、特征的数据也是通过CBPeripheralDelegate回调
#pragma mark-- 特征的数据也是通过CBPeripheralDelegate回调:
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
NSLog(@"peripheral:%@ \n\n characteristic:%@ \n\n error:%@",peripheral, characteristic, error);
[peripheral readValueForCharacteristic:characteristic];
}
9、蓝牙返回数据 代理方法 :这里可能会出现 Reading is not permitted 或则 Writing is not permitted 出现这个 问题不要着急 首先检查 硬件给你的 读写UUID是否正确 如果正确 再次检查 第七步 ( [self.currentPer writeValue: data forCharacteristic:character type:CBCharacteristicWriteWithoutResponse]; )中的 type是否与硬件返回的一致 确保这两点基本没有什么问题了
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
if (error) {
NSLog(@"%@",error);
} else {
NSData *responseData = characteristic.value;
NSLog(@"%@",responseData);
//注意:蓝牙返回的也是 NSData类型的数据 拿到数据解析数据就就可以了
[self auxCmdParse:responseData];//这一步是解析数据
}
}
补充:
向蓝牙发送数据包(数据包的格式跟硬件协商好)
- (NSData*)getData{
NSString *ssid = self.ssid;
NSString *key= self.password;
NSString *paas_address= self.paas_address;
NSString *m2m_address= self.m2m_address;
NSString *apCode= self.apCode;;
NSMutableData *allMData = [[NSMutableData alloc] init];
NSData *ssidData = [ssid dataUsingEncoding: NSUTF8StringEncoding];
NSData *keyData = [key dataUsingEncoding: NSUTF8StringEncoding];
NSData *paas_addressData = [paas_address dataUsingEncoding:NSUTF8StringEncoding];
NSData *m2m_addressData = [m2m_address dataUsingEncoding:NSUTF8StringEncoding];
NSData *apcodeData = [apCode dataUsingEncoding:NSUTF8StringEncoding];
unsigned long length = 8+(ssidData.length)+(keyData.length)+(apcodeData.length)+(m2m_addressData.length)+(paas_addressData.length)+7;
Byte bhead[]= {0xa5, 0xa5, length & 0xFF, 0x00, 0x01, 0x00, 0x00,0x00};
[allMData appendBytes:bhead length:8];
Byte blen[]= {ssidData.length & 0xFF};
[allMData appendBytes:blen length:1];
if (blen[0]>0){
[allMData appendBytes:[ssidData bytes] length:blen[0]];
}
// //
blen[0]= keyData.length & 0xFF;
[allMData appendBytes:blen length:1];
if (blen[0]>0){
[allMData appendBytes:[keyData bytes] length:blen[0]];
}
blen[0]= apcodeData.length & 0xFF;
[allMData appendBytes:blen length:1];
if (blen[0]>0){
[allMData appendBytes:[apcodeData bytes] length:blen[0]];
}
// //
blen[0]= paas_addressData.length & 0xFF;
[allMData appendBytes:blen length:1];
if (blen[0]>0){
[allMData appendBytes:[paas_addressData bytes] length:blen[0]];
}
//
//
blen[0]= m2m_addressData.length & 0xFF;
[allMData appendBytes:blen length:1];
if (blen[0]>0){
[allMData appendBytes:[m2m_addressData bytes] length:blen[0]];
}
int crc= [CRC crc16CCIT:allMData andLen:(int)allMData.length];
Byte bcrc[]= {(crc>>8)&0x0ff, crc&0x0ff};
[allMData appendBytes:bcrc length:2];
return allMData;
}
接收蓝牙发来的数据包(按照规定的顺序解包)
- (Boolean)cmdParse:(NSData *)data{
Byte *b= (Byte *)[data bytes];
if (b[0]== 0xa5 && b[1]== 0xa5
&& b[4]== 0x01 && b[5]== 0x10
&& b[6]== 0x00 && b[7]== 0x00
&& b[8]== 0x00 && b[9]== 0x00){
int crcCal= [CRC crc16CCIT:data andLen:(int)data.length-2];
int crcRcv= ((b[data.length-2] & 0x0ff) << 8) | (b[data.length-1] & 0x0ff);
if (crcCal == crcRcv){
_auxRplMac= [NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X", b[11], b[12], b[13], b[14], b[15], b[16]];
_auxRplPasscode= [self toHexString:b start:18 Len:b[17]];
NSLog(@"%@",_auxRplMac);
NSLog(@"%@",_auxRplPasscode);
return true;
}
}
return false;
}
- (NSString *)toHexString:(Byte *)b start:(int)start Len:(int)len{
NSString *str= @"";
for (int i=0; i<len; i++){
str= [NSString stringWithFormat:@"%@%02X", str, b[start+i]];
}
return str;
}
网友评论