这是一篇旧文,三年前就写过了,一直没有时间分享出来,最近简单整理了下,希望能帮到有需要的人。
  由于我这里没有相关的蓝牙设备,主要用了两个手机,一个作为主设备,一个做为从设备。另外进行蓝牙开发有一个调试利器。

主设备和从设备我分别创建了一个管理类。
主设备主要进行的操作如下:

  • 开始扫描设备
  • 停止扫描设备
  • 连接设备
  • 断开连接设备
  • 发送数据

具体源码如下:

#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>NS_ASSUME_NONNULL_BEGIN@interface JKBlueToothCenterHelper : NSObject
/// 设备管理者状态block
@property (nonatomic, copy) void(^btStatusBlock)(NSInteger status,NSString *message);
/// 设备连接状态的block
@property (nonatomic, copy) void(^btConnectStatusBlock)(CBPeripheral *peripheral, NSError * _Nullable error);
/// 断开链接block
@property (nonatomic, copy) void(^btDisconnectStatusBlock)(CBPeripheral *peripheral, NSError * _Nullable error);
/// 扫描到的设备列表block
@property (nonatomic,copy) void(^btScanDevicesBlock)(NSMutableArray <CBPeripheral *>*devices);/// 接收到数据的block
@property (nonatomic,copy) void(^receivedDataBlock)(NSData *data, NSError *error);/**开始扫描设备@param services 扫描的服务@param options 扫描的选项配置@param containDefaultService 是否包含默认的服务@return JKBlueToothCenterHelper 对象*/
- (instancetype)initWithScanServices:(nullable NSArray<CBUUID *> *)services options:(nullable NSDictionary <NSString *, id> *)options containDefaultService:(BOOL)containDefaultService;/**
扫描设备*/
- (void)scanDevice;/**停止扫描设备*/
- (void)stopScanDevice;/**连接设备@param peripheral 设备@param options 配置信息*/
- (void)connectToDevice:(CBPeripheral *)peripheral options:(NSDictionary <NSString *, id> *)options;/**断开连接设备@param peripheral 设备*/
- (void)disconnectToDevice:(CBPeripheral *)peripheral;/**设备管理者向设备发送数据@param data 二进制数据@param peripheral 接受数据的设备@param CBCharacteristic 特征@param type 请求类型*/
- (void)sendData:(NSData *)data toPeripheral:(CBPeripheral *)peripheral forCharacteristic:(CBCharacteristic *)CBCharacteristic type:(CBCharacteristicWriteType)type complete:(void(^)(NSError *error))completeBlock;@endNS_ASSUME_NONNULL_END
typedef void(^JKBTCenterSendCompleteBlock)(NSError *error);@interface JKBlueToothCenterHelper()<CBCentralManagerDelegate,CBPeripheralDelegate>@property (nonatomic, strong) CBCentralManager  *centerManager; ///< 管理者
@property (nonatomic, strong) NSMutableArray *scanServices;            ///< 扫描的服务
@property (nonatomic, strong) NSDictionary <NSString *, id>      *scanOptions; ///< 扫描的配置
@property (nonatomic,strong) NSMutableArray *scannedDevices; ///< s扫描到的设备
@property (strong , nonatomic) CBPeripheral * discoveredPeripheral;//周边设备
@property (nonatomic,copy) JKBTCenterSendCompleteBlock sendCompleteBlock;@end@implementation JKBlueToothCenterHelper
- (instancetype)initWithScanServices:(nullable NSArray<CBUUID *> *)services options:(nullable NSDictionary <NSString *, id> *)options containDefaultService:(BOOL)containDefaultService{self = [super init];if (self) {[self.scanServices addObjectsFromArray:services];if (containDefaultService) {[self setupDefalutScanService];}self.scanOptions = options;[self centerManager];}return self;
}- (void)setupDefalutScanService{CBUUID *uuid = [CBUUID UUIDWithString:DEFAULT_SERVICE_UUID];[self.scanServices addObject:uuid];}- (void)scanDevice{[self.scannedDevices removeAllObjects];[self.centerManager scanForPeripheralsWithServices:self.scanServices options:self.scanOptions];
}- (void)stopScanDevice{[self.centerManager stopScan];
}- (void)connectToDevice:(CBPeripheral *)peripheral options:(NSDictionary <NSString *, id> *)options{self.discoveredPeripheral = peripheral;self.discoveredPeripheral.delegate = self;[self.centerManager connectPeripheral:peripheral options:options];
}- (void)disconnectToDevice:(CBPeripheral *)peripheral{[self.centerManager cancelPeripheralConnection:peripheral];
}- (void)sendData:(NSData *)data toPeripheral:(CBPeripheral *)peripheral forCharacteristic:(CBCharacteristic *)CBCharacteristic type:(CBCharacteristicWriteType)type complete:(void(^)(NSError *error))completeBlock{self.sendCompleteBlock = completeBlock;[peripheral writeValue:data forCharacteristic:CBCharacteristic type:type];
}#pragma mark - - - - CBCentralManagerDelegate - - - -
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{if (@available(iOS 10.0, *)) {switch (central.state) {case CBManagerStatePoweredOn://蓝牙打开{[self.centerManager scanForPeripheralsWithServices:self.scanServices options:self.scanOptions];}break;case CBManagerStatePoweredOff://蓝牙关闭了{if (self.btStatusBlock) {self.btStatusBlock(CBManagerStatePoweredOff, @"蓝牙已关闭,请打开蓝牙");}}break;case CBManagerStateUnsupported://不支持{if (self.btStatusBlock) {self.btStatusBlock(CBManagerStatePoweredOff, @"蓝牙设备不支持!");}}break;default:break;}} else {// Fallback on earlier versionsswitch (central.state) {case 5://蓝牙打开{[self.centerManager scanForPeripheralsWithServices:self.scanServices options:self.scanOptions];}break;case 4://蓝牙关闭了{if (self.btStatusBlock) {self.btStatusBlock(4, @"蓝牙已关闭,请打开蓝牙");}}break;case 2://不支持{if (self.btStatusBlock) {self.btStatusBlock(2, @"蓝牙设备不支持!");}}break;default:break;}}}- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI{if (!peripheral) {return;}[peripheral discoverServices:self.scanServices];if (![self.scannedDevices containsObject:peripheral]) {[self.scannedDevices addObject:peripheral];if (self.btScanDevicesBlock) {self.btScanDevicesBlock(self.scannedDevices);}}}- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(nonnull CBPeripheral *)peripheral error:(nullable NSError *)error{if (self.btConnectStatusBlock) {self.btConnectStatusBlock(peripheral, error);}
}- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{if (@available(iOS 9.0, *)) {if (self.centerManager.isScanning) {[self stopScanDevice];}} else {// Fallback on earlier versions[self stopScanDevice];}self.discoveredPeripheral = peripheral;[peripheral setDelegate:self];[peripheral discoverServices:nil];if (self.btConnectStatusBlock) {self.btConnectStatusBlock(peripheral, nil);}
}- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(nonnull CBPeripheral *)peripheral error:(nullable NSError *)error{if (self.btDisconnectStatusBlock) {self.btDisconnectStatusBlock(peripheral, error);}
}//- (void)centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary<NSString *, id> *)dict{
//
//}#pragma mark - - - - CBPeripheralDelegate - - - -
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(nullable NSError *)error{peripheral.delegate = self;NSArray *services = peripheral.services;for (CBService *service in services) {[peripheral discoverCharacteristics:nil forService:service];}
}- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(nullable NSError *)error{for (CBCharacteristic *characteristic in service.characteristics) {if ([[NSString stringWithFormat:@"%@",characteristic.UUID] isEqualToString: DEFAULT_CHARACTERISTIC_UUID]) {[self.discoveredPeripheral setNotifyValue:YES forCharacteristic:characteristic];}}}// 写入成功
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error {if (self.sendCompleteBlock) {self.sendCompleteBlock(error);}
}-(void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {if (error) {//NSLog(@"订阅失败");//NSLog(@"%@",error);}if (characteristic.isNotifying) {//NSLog(@"订阅成功");} else {//NSLog(@"取消订阅");}
}- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{[peripheral readValueForCharacteristic:characteristic];NSData *data = characteristic.value;if (self.receivedDataBlock) {self.receivedDataBlock(data,error);}
}#pragma mark - - - - lazyLoad - - - -
- (CBCentralManager *)centerManager{if (!_centerManager) {dispatch_queue_t queue = dispatch_queue_create("com.btCenterManager.queue", 0);CBCentralManager *centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:queue options:nil];centralManager.delegate = self;_centerManager = centralManager;}return _centerManager;
}- (NSMutableArray *)scannedDevices{if (!_scannedDevices) {_scannedDevices = [NSMutableArray new];}return _scannedDevices;
}- (NSMutableArray *)scanServices{if (!_scanServices) {_scanServices = [NSMutableArray new];}return _scanServices;
}@end

从设备进行的操作如下:

  • 添加服务
  • 开始广播
  • 停止广播
  • 发送数据
    具体源码如下:
#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>typedef void(^JKBTPeripheralStatusBlock)(NSInteger status,NSString *message);
typedef void(^JKBTPeripheralRecievedDataBlock)(NSData *data,NSError *error);@interface JKBlueToothPeripheralHelper : NSObject@property (nonatomic,copy) JKBTPeripheralStatusBlock btStatusBlock;///< 蓝牙状态的block
@property (nonatomic,copy) JKBTPeripheralRecievedDataBlock receivedDataBlock;/**初始化JKBlueToothPeripheralHelper 对象@param services 提供的服务数组@param adContent 广播内容*/
- (void)addServices:(NSArray <CBMutableService *>*)services adContent:(NSDictionary *)adContent;/**添加默认的服务*/
- (void)addDefaultService;/**开始广播*/
- (void)startAdvertising;/**停止广播*/
- (void)stopAdvertising;/**
发送数据到设备管理器@param data 二进制数据@param centerDevices 主设备@param characteristic 特征*/
- (void)sendData:(NSData *)data toCenterManagers:(NSArray <CBCentral*>*)centerDevices forCharacteristic:(CBMutableCharacteristic *)characteristic;@end
#import "JKBlueToothPeripheralHelper.h"
#import <CoreBluetooth/CoreBluetooth.h>
#import <UIKit/UIKit.h>
#import "JKBlueToothMacro.h"
@interface JKBlueToothPeripheralHelper()<CBPeripheralManagerDelegate>
@property (nonatomic,strong)CBPeripheralManager *peripheralManager;
@property (nonatomic,strong) NSDictionary *adContent;        ///< 广播内容
@property (nonatomic,strong) CBMutableService *defaultService; ///< 默认提供的服务
@property (nonatomic,strong) CBMutableCharacteristic *defaultCharacteristic; ///< 默认具有的特征
@property (nonatomic,strong) NSMutableArray <CBMutableService *>*services;
@property (nonatomic,strong) NSMutableArray <CBCentral *>*centrals;
@end@implementation JKBlueToothPeripheralHelper- (void)addServices:(NSArray <CBMutableService *>*)services adContent:(NSDictionary *)adContent{if (!self.peripheralManager) {dispatch_queue_t queue = dispatch_queue_create("com.btPeripheralManager.queue", 0);self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:queue];}if (services.count>0) {[self.services addObjectsFromArray:services];}self.adContent = adContent;}- (void)addDefaultService{CBUUID *serviceID = [CBUUID UUIDWithString:DEFAULT_SERVICE_UUID];CBMutableService *service = [[CBMutableService alloc] initWithType:serviceID primary:YES];// 创建服务中的特征CBUUID *characteristicID = [CBUUID UUIDWithString:DEFAULT_CHARACTERISTIC_UUID];CBMutableCharacteristic *characteristic = [[CBMutableCharacteristic alloc]initWithType:characteristicIDproperties:CBCharacteristicPropertyRead |CBCharacteristicPropertyWrite |CBCharacteristicPropertyNotifyvalue:nilpermissions:CBAttributePermissionsReadable |CBAttributePermissionsWriteable];// 特征添加进服务[JKBlueToothModule service:service addCharacteristic:characteristic];self.defaultCharacteristic = characteristic;self.defaultService = service;[self.services addObject:self.defaultService];
}- (void)startAdvertising{[self.peripheralManager startAdvertising:self.adContent];
}- (void)stopAdvertising{[self.peripheralManager stopAdvertising];
}- (void)sendData:(NSData *)data toCenterManagers:(NSArray <CBCentral*>*)centerDevices forCharacteristic:(CBMutableCharacteristic *)characteristic{characteristic = characteristic?:self.defaultCharacteristic;if (!centerDevices || centerDevices.count == 0) {centerDevices = self.centrals;}[self.peripheralManager updateValue:data forCharacteristic:characteristic onSubscribedCentrals:centerDevices];
}#pragma mark - - - - CBPeripheralManagerDelegate - - - -
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral{if (@available(iOS 10.0, *)) {switch (peripheral.state) {case CBManagerStatePoweredOn://蓝牙打开{for (CBMutableService *service in self.services) {[self.peripheralManager addService:service];}[self startAdvertising];}break;case CBManagerStatePoweredOff://蓝牙关闭了{if (self.btStatusBlock) {self.btStatusBlock(CBManagerStatePoweredOff, @"蓝牙已关闭,请打开蓝牙");}}break;case CBManagerStateUnsupported://不支持{if (self.btStatusBlock) {self.btStatusBlock(CBManagerStatePoweredOff, @"蓝牙设备不支持!");}}break;default:break;}} else {// Fallback on earlier versionsswitch (peripheral.state) {case 5://蓝牙打开{for (CBMutableService *service in self.services) {[self.peripheralManager addService:service];}[self startAdvertising];}break;case 4://蓝牙关闭了{if (self.btStatusBlock) {self.btStatusBlock(4, @"蓝牙已关闭,请打开蓝牙");}}break;case 2://不支持{if (self.btStatusBlock) {self.btStatusBlock(2, @"蓝牙设备不支持!");}}break;default:break;}}
}-(void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error{}- (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];
//    }}- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray<CBATTRequest *> *)requests {CBATTRequest *request = requests.lastObject;if (request.characteristic.properties & CBCharacteristicPropertyWrite) {CBMutableCharacteristic *characteristic = (CBMutableCharacteristic *)request.characteristic;characteristic.value = request.value;if (self.receivedDataBlock) {self.receivedDataBlock(request.value,nil);}[self.peripheralManager respondToRequest:request withResult:CBATTErrorSuccess];} else {if (self.receivedDataBlock) {NSError *error = [[NSError alloc] initWithDomain:@"JKBlueToothModule" code:CBATTErrorWriteNotPermitted userInfo:@{@"msg":@"CBATTErrorWriteNotPermitted error"}];self.receivedDataBlock(nil,error);}[self.peripheralManager respondToRequest:request withResult:CBATTErrorWriteNotPermitted];}
}//订阅characteristics
-(void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic{//NSLog(@"订阅了 %@的数据",characteristic.UUID);[self.centrals addObject:central];}//取消订阅characteristics
-(void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic{//NSLog(@"取消订阅 %@的数据",characteristic.UUID);[self.centrals removeObject:central];}#pragma mark - - - - lazyLoad - - - -
- (NSMutableArray *)services{if (!_services) {_services  = [NSMutableArray new];}return _services;
}- (NSMutableArray *)centrals{if (!_centrals) {_centrals = [NSMutableArray new];}return _centrals;
}@end

代码可以直接复制直接使用。由于我这边是私有库,就不开放给大家了。另外文件传输时,参考我之前写的一篇文章《iOS蓝牙开发之数据传输精华篇》
里面有讲到数据拼接的一个工具 ,pod集成如下:

pod 'JKTransferDataHelper'

iOS 蓝牙开发实现文件传输相关推荐

  1. iOS蓝牙开发数据实时传输

    随着iOS项目开发  很多app需要通过蓝牙与设备连接 蓝牙开发注意: 先定义中心设备和外围设备以及遵守蓝牙协议 @interface ViewController()<CBCentralMan ...

  2. iOS蓝牙开发---CoreBluetooth[BLE 4.0] 初级篇[内附Demo地址]

    一.蓝牙基础知识 (一)常见简称 1.MFI  make for ipad ,iphone, itouch 专们为苹果设备制作的设备,开发使用ExternalAccessory 框架(认证流程貌似挺复 ...

  3. iOS 蓝牙开发 BabyBluetooth蓝牙库介绍

    BabyBluetooth 是一个最简单易用的蓝牙库,基于CoreBluetooth的封装,并兼容iOS和Mac OS X. 特色: 基于原生CoreBluetooth框架封装的轻量级的开源库,可以帮 ...

  4. iOS 蓝牙开发资料记录

    一.蓝牙基础认识:   1.iOS蓝牙开发:   iOS蓝牙开发:蓝牙连接和数据读写   iOS蓝牙后台运行  iOS关于app连接已配对设备的问题(ancs协议的锅)          iOS蓝牙空 ...

  5. 求用C#开发的文件传输实例

    求用C#开发的文件传输实例,希望大家能够帮帮忙. 我的邮箱:panhaizhou128@sina.com

  6. ios 蓝牙开发总结

    随着蓝牙低功耗技术BLE(Bluetooth Low Energy)的发展,蓝牙技术正在一步步成熟,如今的大部分移动设备都配备有蓝牙4.0,相比之前的蓝牙技术耗电量大大降低.从iOS的发展史也不难看出 ...

  7. iOS蓝牙开发(三):iOS中蓝牙模块OTA升级(YModem协议)

    上一篇简单介绍了蓝牙4.0的iOS实现代码,详细的东西大家可以去github上搜babyBluetooth,里面有一些学习资料,接下来分享的是OTA升级的东西,我们假定看这篇文章的时候,关于iOS和外 ...

  8. iOS蓝牙开发:蓝牙连接和数据读写

    当下蓝牙开发可谓是越来越火,不论是智能穿戴的兴起还是蓝牙家具,车联网蓝牙等等,很多同学也会接触到蓝牙的项目,我从事蓝牙开发也有一段时间了,经手了两个项目.废话不多说了,先向大家简单的介绍有关蓝牙开发的 ...

  9. android 蓝牙 bluetooth OPP文件传输

    蓝牙文件分享的流程,也就是蓝牙应用opp目录下的代码,作为蓝牙最基本的一个功能,这部分的代码在之前的版本中就已经有了,新旧版本代码对比很多类名都是一样的,这一部分新东西不多,写在这里帮助大家梳理下流程 ...

  10. Andorid/IOS 蓝牙开发总结

    IOS 蓝牙 ios 蓝牙依赖CoreBluetooth 库 1 首先增加库 CoreBluetooth    general-> Linked Frameworks and lib 2 权限i ...

最新文章

  1. Oracle - 数据库的实例、表空间、用户、表之间关系
  2. 【高并发】一个工作了7年的朋友去面试竟然被Thread类虐的体无完肤
  3. TranslateMessage()的困惑
  4. input onblur事件在chrome/safari中失效
  5. The type java.lang.Object cannot be resolved
  6. c 最大子序列和_算法总结:左神class8—跳台阶+最长递增公共子序列
  7. deferred Transports Protocols 简单介绍
  8. 【HDU - 6558】The Moon(期望dp)
  9. Python发送文本邮件
  10. 论文摘要这么重要,你却不知道怎么写?
  11. 上传文件时显示选择窗口
  12. 一文总结More Effective c++
  13. php微信转跳浏览器代码,通用微信QQ跳转浏览器打开代码
  14. Cgroup学习之——Ubuntu下交叉编译ARM平台libcgroup工具
  15. 鸡兔同笼c语言代码while,鸡兔同笼(C语言代码)
  16. java进销存--商品管理
  17. css中只读,是否可以通过CSS将输入字段设置为只读?
  18. js简单实现百度地图雷达探测效果
  19. 学历查询,邮件查询,身份证查询,聊天室查询,日期时间查询,列车飞机航班查询,等各种各类的查询网
  20. rua出300道四则运算题

热门文章

  1. Hadoop组件搭建-Hadoop全分布式
  2. vim替换字符串命令详解
  3. Windows下的Tomcat7安装与环境配置
  4. LiveGBS/LiveNVR组合实现GB35114平台端和GB35114设备端的GB35114的交互流程
  5. c语言编程运行符号是什么,c语言编程用的符号有哪些
  6. ANSYS 15 直接优化分析
  7. Endnote导出GB/T 7714-2015 格式参考文献
  8. 解决台式机外放和插耳机都没声音[基础版]
  9. 对WordCOM类工厂80070005和8000401a错误分析及解决办法(DCOM)的补充
  10. python求解线性规划问题