iOS 蓝牙开发

042ec9e15de70b28500fa5b9e06883be.jpg

不想写太多字、所以就直接粘贴代码了
1、实现蓝牙单连接
2、实现蓝牙重连
3、实现蓝牙简单发送指令

这个Demo是16年写的了、最近才开始写简书的,所以就把这个分享给大家

//
//  MBBlueToothManager.m
//  MBDemo
//  Created by kcl on 16/12/28.
//  Copyright © 2016年 kcl. All rights reserved.
//

#import "MBBlueToothManager.h"


@interface MBBlueToothManager()<CBPeripheralDelegate,CBCentralManagerDelegate>{

   CBCentralManager *manager;
   CBUUID *identifiers;
   NSData *_dataValue;
   L2_command_id_t _keyId;
   UInt8 _moudleId;
   NSMutableArray *connectDevice;
}
@end
static MBBlueToothManager *manager;

@implementation MBBlueToothManager

- (instancetype)init
{
   self = [super init];
   if (self) {
      pairDeviceMutArr = [[NSMutableArray alloc]init];
   }
   return self;
}
+ (instancetype)shareManager
{
   if (manager == nil) {
      manager = [[MBBlueToothManager alloc]init];
   }
   return manager;
}
- (void)startScan
{
   manager = [[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_main_queue()];

   if (manager.state != CBCentralManagerStatePoweredOn) {
//      [self alertWithTitle:@"蓝牙未打开" Message:nil certainActionString:@"确定" cancelActionString:@"取消"];
//      return;
      NSLog(@"=====please open your BlueTooth");
   }
   NSLog(@"============= startScan");

   [self RetryConnectSaveDevice];
}
- (void)stopScan
{
   [manager stopScan];
}
- (void)tryToConnect:(CBPeripheral *)pairDevice
{
//   [manager stopScan];
   NSLog(@"开始连接设备:%@",pairDevice.name);
//   NSDictionary *options = @{CBConnectPeripheralOptionNotifyOnDisconnectionKey: @TRUE};
   [manager connectPeripheral:pairDevice options:nil];
}
- (void)disConnectDevice
{
   if (self.device.state != CBPeripheralStateConnected) {
      return;
   }
   [manager cancelPeripheralConnection:self.device];
}

#pragma mark -CBPeripheralDelegate
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
   CBManagerState state = central.state;

   switch (state) {
      case CBCentralManagerStateUnknown:

         break;
      case CBCentralManagerStatePoweredOn:

            [manager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey:@YES}];

         break;
      case CBCentralManagerStatePoweredOff:
         [self disConnectDevice];
         break;
      case CBCentralManagerStateUnsupported:
         break;
      case CBCentralManagerStateUnauthorized:
         break;
      default:
         break;
   }
}
- (void)RetryConnectSaveDevice
{
   NSString *uuidStr = [[NSUserDefaults standardUserDefaults] stringForKey:DidConnectDeviceUUID];

   NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:uuidStr];
   if (uuidStr != nil) {

      NSArray *arr = [manager retrievePeripheralsWithIdentifiers:@[uuid]];
      for (CBPeripheral *aperipheral in arr) {
//         if ([aperipheral.identifier.UUIDString isEqualToString: peripheral.identifier.UUIDString]) {
            NSLog(@"connectPeripheral =======  %@",[aperipheral debugDescription]);
            [manager connectPeripheral:aperipheral options:nil];
            //                  [manager stopScan];
//         }
      }

   }else{
   }
}
//这个地方是自定义的模式、我们公司的设备就是这样的
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI
{
   MBDeviceModel *model = [[MBDeviceModel alloc] init];
   model.device = peripheral;

   NSString *macStr = [[NSString alloc] init];
   NSString *peripheralName = advertisementData[@"kCBAdvDataLocalName"];
   if (advertisementData[@"kCBAdvDataServiceUUIDs"]) {
      NSArray *array = advertisementData[@"kCBAdvDataServiceUUIDs"];
      if (array.count>=6) {
         NSMutableData *tData = [[NSMutableData alloc]initWithCapacity:6];
         CBUUID *uuid3 = array[5];
         NSData *data3 = uuid3.data;
         [tData appendData:data3];
         CBUUID *uuid2 = array[4];
         NSData *data2 = uuid2.data;
         [tData appendData:data2];
         CBUUID *uuid1 = array[3];
         NSData *data1 = uuid1.data;
         [tData appendData:data1];
         macStr = [tData macAddrString];
      }
   }
   model.deviceName = peripheralName;
   model.macString = macStr;

//   if ([peripheral.identifier.UUIDString isEqualToString:[[NSUserDefaults standardUserDefaults] stringForKey:DidConnectDeviceUUID]]) {
//      [manager connectPeripheral:peripheral options:nil];
//   }

   if ([peripheral.name containsString:@"MB12"]) {
      [[NSNotificationCenter defaultCenter] postNotificationName:kJRDUpdatePeripheralList object:model];

   }else{
      
   }

}

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
   [manager stopScan];
   NSLog(@"didConnectPeripheral = %@",peripheral.name);
   self.device = peripheral;
   [[NSUserDefaults standardUserDefaults] setObject:peripheral.identifier.UUIDString forKey:DidConnectDeviceUUID];
    peripheral.delegate = self;
   [peripheral discoverServices:nil];

}
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
   NSLog(@"didFailToConnectPeripheral = %@",peripheral.name);
   [[NSNotificationCenter defaultCenter] postNotificationName:kBHBLEUartDeviceConnectFailNotification object:nil];
}
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
   NSLog(@"didDisconnectPeripheral = %@",peripheral.name);
}


#pragma mark - CBPeripheralDelegate
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
   NSLog(@"deviceName = %@ ,didDiscoverServices = %@",peripheral.name,peripheral.services);
   for(CBService *svc in peripheral.services )
   {
      [peripheral discoverCharacteristics:nil forService:svc];
   }
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
   NSLog(@"deviceName = %@ ,didDiscoverCharacteristicsForService = %@",peripheral.name,service.characteristics);
   for (CBCharacteristic *character in service.characteristics) {

      if ([[character.UUID UUIDString] isEqual:kBAIDU_HEALTH_BRACELET_UART_RX_CHARACTER_UUID_STRING])
      {
         [peripheral setNotifyValue:YES forCharacteristic:character];
          [[NSNotificationCenter defaultCenter] postNotificationName:kBHBLEUartDeviceConnectOKNotification object:nil];
         NSLog(@"character = %@",character);
      }
    }
}

- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForDescriptor:(CBDescriptor *)descriptor error:(NSError *)error
{
   if (!error) {
      NSLog(@"数据写入成功");
   }else{
      NSLog(@"数据写入失败");
   }
}
- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
   NSLog(@"didUpdateNotificationStateForCharacteristic");
   CBUUID *characteristicUUID = [CBUUID UUIDWithString:kBAIDU_HEALTH_BRACELET_UART_RX_CHARACTER_UUID_STRING];
   if ([characteristic.UUID isEqual:characteristicUUID]) {
      if (characteristic.isNotifying) {
         if (characteristic.properties == CBCharacteristicPropertyNotify) {
            NSLog(@"value ====  %@",characteristic.value);
            return;
         }else if(characteristic.properties == CBCharacteristicPropertyRead){
            NSLog(@"value ====  %@",characteristic.value);
            [peripheral readValueForCharacteristic:characteristic];
         }
      }else{

      }
   }
}
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
   if (error) {
      return;
   }else{

   }
   NSLog(@"value = ========== %@",characteristic.value);
   if (characteristic.value){
      NSString *value = [[NSString alloc]initWithData:characteristic.value encoding:NSUTF8StringEncoding];
   }else{
      NSLog(@"");
   }
}
//- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForDescriptor:(CBDescriptor *)descriptor error:(NSError *)error
//{
//   NSLog(@"didUpdateValueForDescriptor");
//   if (descriptor.characteristic) {
//
//      [peripheral readValueForCharacteristic:descriptor.characteristic];
//      NSLog(@"readValue == %@",descriptor.value);
//
//   }
//
//}
- (void)writeDataToUratWithKeyId:(UInt8)keyId moudleId:(UInt8)moudleId datavalue:(NSData *)dataValue
{
   _dataValue = dataValue;
   _keyId = keyId;
   _moudleId = moudleId;
   NSLog(@"开始写入数据 =========keyid=%u ,moduleId = %hhu",keyId,moudleId);
   for (CBService *service in self.device.services) {
      for (CBCharacteristic *character in service.characteristics) {

         if ([[character.UUID UUIDString] isEqualToString:kBAIDU_HEALTH_BRACELET_UART_TX_CHARACTER_UUID_STRING]) {

            NSLog(@"forCharacteristic ====== %@",character);
            NSLog(@"=======senddata == %@",[self package]);
            [self.device writeValue:[self package] forCharacteristic:character type:CBCharacteristicWriteWithoutResponse];
         }else{

         }
      }
   }
}
- (NSData *)package
{
   NSMutableData *header = [[NSMutableData alloc]initWithCapacity:16];
   UInt16 magic = L_Magic;
   NSData *magicData = [NSData dataWithBytes:&magic length:sizeof(UInt16)];
   [header appendData:magicData];
   UInt16 length = L_Head_length;
   if (_dataValue) {
      length = [_dataValue length] + L_Head_length;
      NSData *lengthData = [NSData dataWithBytes:&length length:sizeof(UInt16)];
      [header appendData:lengthData];
   }else{
      NSData *lengthData = [NSData dataWithBytes:&length length:sizeof(UInt16)];
      [header appendData:lengthData];
   }
   UInt8 packageType = L_PackageTypeSend;
   NSData *packageTypeData = [NSData dataWithBytes:&packageType length:sizeof(UInt8)];
   [header appendData:packageTypeData];
   UInt8 tversion = L_Version;
   NSData *vr = [NSData dataWithBytes:&tversion length:sizeof(UInt8)];
   [header appendData:vr];
   NSData *keyIdData = [NSData dataWithBytes:&_keyId length:sizeof(UInt8)];
   [header appendData:keyIdData];
   NSData *moudleData = [NSData dataWithBytes:&_moudleId length:sizeof(UInt8)];
   [header appendData:moudleData];
   if (_dataValue) {
      [header appendData:_dataValue];
   }
   return header;
}


- (void)alertWithTitle:(NSString *)alertTitle Message:(NSString *)message certainActionString:(NSString *)certainActionString cancelActionString:(NSString *)cancelActionString
{
   UIAlertController *alertCtr = [UIAlertController alertControllerWithTitle:alertTitle message:message preferredStyle:UIAlertControllerStyleActionSheet];
   UIAlertAction *certainAction = [UIAlertAction actionWithTitle:certainActionString style:UIAlertActionStyleDefault handler:nil];
   [alertCtr addAction:certainAction];
   UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:cancelActionString style:UIAlertActionStyleCancel handler:nil];
   [alertCtr addAction:cancelAction];
   UIViewController *ctr = [UIApplication sharedApplication].keyWindow.rootViewController;
   [ctr presentViewController:ctr animated:YES completion:nil];
}

@end

  • 代码里面我一般不会写注释、因为这是我自己写的我能看得懂。

使用这一套可以完成蓝牙简单的需求、有不懂的可以问我、大家一起交流

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,233评论 6 495
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,357评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,831评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,313评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,417评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,470评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,482评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,265评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,708评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,997评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,176评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,827评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,503评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,150评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,391评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,034评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,063评论 2 352