项目中要使用到蓝牙连接,研究了下,做了简单的封装,简单的项目都可以直接使用,复杂的主要考虑数据的处理,结合自身项目和硬件沟通,一步步来吧!!!
在这里给广大初入蓝牙的iOS同学做个参考
直接上代码.h文件
#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>
NS_ASSUME_NONNULL_BEGIN
@protocol LSSBluetoothManagerDelegate <NSObject>
- (void)readData:(NSString *)data;
- (void)scanBluetooth:(NSArray <CBPeripheral *>*)equips;
@end
@interface LSSBluetoothManager : NSObject
@property (nonatomic, assign) id <LSSBluetoothManagerDelegate>delegate;
@property (nonatomic, copy) void(^readData)(NSString *data);
@property (nonatomic, copy) void(^equips)(NSArray <CBPeripheral *>*equipsArray);
@property (nonatomic, copy) NSString *tocken;
+ (instancetype)blueManager;
- (void)startScanBluetooth;
- (void)connectBluetooth:(CBPeripheral *)peripheral;
- (void)sendData:(NSString *)data;
- (void)disconnectBluetooth;
@end
NS_ASSUME_NONNULL_END
.m文件
#import "LSSBluetoothManager.h"
#define ServiceUUID @"fee7"
#define ReadUUID @"36f6"
#define WriteUUID @"36f5"
@interface LSSBluetoothManager() <CBCentralManagerDelegate,CBPeripheralDelegate>
@property (nonatomic, strong) CBCentralManager *manager;
@property (nonatomic, strong) CBPeripheral *peripheral;
@property (nonatomic, strong) CBCharacteristic *writeCha;
@property (nonatomic, strong) CBCharacteristic *readCha;
@property (nonatomic, strong) NSMutableArray <CBPeripheral *>*equipmentsArray;
@property (nonatomic, copy) NSString *macAddress;
@end
@implementation LSSBluetoothManager
+ (instancetype)blueManager{
static LSSBluetoothManager *manager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[LSSBluetoothManager alloc]init];
});
return manager;
}
- (CBCentralManager *)manager
{
if (!_manager)
{
_manager = [[CBCentralManager alloc]initWithDelegate:self queue:nil];
}
return _manager;
}
- (NSMutableArray <CBPeripheral *>*)equipmentsArray
{
if (!_equipmentsArray)
{
_equipmentsArray = [NSMutableArray array];
}
return _equipmentsArray;
}
- (void)startScanBluetooth
{
if (self.manager.isScanning)
{
[self.manager stopScan];
}
// if (@available(iOS 10.0, *)) {
// if (self.manager.state == CBManagerStatePoweredOn) {
// [self.manager scanForPeripheralsWithServices:nil options:nil];
// }
// } else if (self.manager.state == CBCentralManagerStatePoweredOn) {
// [self.manager scanForPeripheralsWithServices:nil options:nil];
// }
}
//连接蓝牙
- (void)connectBluetooth:(CBPeripheral *)peripheral
{
[self disconnectBluetooth];
[self.manager connectPeripheral:peripheral options:nil];
}
//写入数据
- (void)sendData:(NSString *)data{
[self sendDataToBluetooth:[self dataWithHexstring:data]];
}
//断开链接
- (void)disconnectBluetooth
{
if (self.peripheral)
{
[self.manager cancelPeripheralConnection:self.peripheral];
}
}
//发送写入数据
- (void)sendDataToBluetooth:(NSData *)data
{
[self.peripheral writeValue:data forCharacteristic:self.writeCha type:CBCharacteristicWriteWithResponse];
}
- (void)centralManagerDidUpdateState:(nonnull CBCentralManager *)central {
switch (central.state) {
case 0://未知状态CBManagerStateUnknown
break;
case 1://设备初始化中CBManagerStateResetting
break;
case 2://不支持蓝牙CBManagerStateUnsupported
break;
case 3://设备未授权CBManagerStateUnauthorized
break;
case 4://蓝牙未开启
break;
case 5://蓝牙已开启CBManagerStatePoweredOn
[self.manager scanForPeripheralsWithServices:nil options:nil];
break;
default:
break;
}
}
//扫描发现设备
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI
{
if (![self.equipmentsArray containsObject:peripheral] && peripheral.name)
{
[self.equipmentsArray addObject:peripheral];
if ([self.delegate respondsToSelector:@selector(scanBluetooth:)]) {
[self.delegate scanBluetooth:self.equipmentsArray];
}
}
}
//连接成功
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
self.peripheral = peripheral;
self.peripheral.delegate = self;
[self.peripheral discoverServices:nil];
[self.manager stopScan];
}
//连接失败
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
NSLog(@"链接失败");
if (self.peripheral)
{
[self.manager connectPeripheral:self.peripheral options:nil];
}
else
{
if (self.manager)
{
[self.manager scanForPeripheralsWithServices:nil options:nil];
}
}
}
//断开链接
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
NSLog(@"已断开");
}
//发现服务
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
for (CBService *service in peripheral.services) {
if ([[service.UUID.UUIDString lowercaseString] isEqualToString:ServiceUUID])
{
[peripheral discoverCharacteristics:nil forService:service];
}
}
}
//发现特征
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
for (CBCharacteristic *cha in service.characteristics) {
if ([[cha.UUID.UUIDString lowercaseString] isEqualToString:WriteUUID])
{
self.writeCha = cha;
[self.peripheral setNotifyValue:YES forCharacteristic:self.writeCha];
}
else if ([[cha.UUID.UUIDString lowercaseString] isEqualToString:ReadUUID])
{
self.readCha = cha;
//注册监听读取数据
[self.peripheral setNotifyValue:YES forCharacteristic:self.readCha];
}
}
}
//读取数据
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
if (characteristic == self.readCha) {
if ([self.delegate respondsToSelector:@selector(readData:)])
{
[self.delegate readData:[self hexadecimalString:characteristic.value]];
}
else if (self.readData)
{
self.readData([self hexadecimalString:characteristic.value]);
}
else
{
[[NSNotificationCenter defaultCenter] postNotificationName:@"BluetoothReadNotification" object:nil userInfo:@{@"read":[self hexadecimalString:characteristic.value]}];
}
}
}
//- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForDescriptor:(CBDescriptor *)descriptor error:(NSError *)error
//{
// NSLog(@"写入成功%@ %@",descriptor.characteristic.UUID.UUIDString,descriptor.value);
//}
-(NSData*)dataWithHexstring:(NSString *)hexstring{
NSMutableData* data = [NSMutableData data];
int idx;
for(idx = 0; idx + 2 <= hexstring.length; idx += 2){
NSRange range = NSMakeRange(idx, 2);
NSString* hexStr = [hexstring substringWithRange:range];
NSScanner* scanner = [NSScanner scannerWithString:hexStr];
unsigned int intValue;
[scanner scanHexInt:&intValue];
[data appendBytes:&intValue length:1];
}
return data;
}
- (NSString*)hexadecimalString:(NSData *)data{
NSString* result;
const unsigned char* dataBuffer = (const unsigned char*)[data bytes];
if(!dataBuffer){
return nil;
}
NSUInteger dataLength = [data length];
NSMutableString* hexString = [NSMutableString stringWithCapacity:(dataLength * 2)];
for(int i = 0; i < dataLength; i++){
[hexString appendString:[NSString stringWithFormat:@"%02lx", (unsigned long)dataBuffer[i]]];
}
result = [NSString stringWithString:hexString];
return result;
}
@end
由于iOS中AES加密的类型参数就来你各种功能,在对接蓝牙的时候又常用到AES nopadding类型,难受的是,iOS似乎不支持,查找资料后找到一个C写的AES加密方法,分享给大家
百度网盘链接 提取码: bmcd
网友评论