日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

iOS 蓝牙开发实现文件传输

發布時間:2023/12/20 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iOS 蓝牙开发实现文件传输 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

??這是一篇舊文,三年前就寫過了,一直沒有時間分享出來,最近簡單整理了下,希望能幫到有需要的人。
??由于我這里沒有相關的藍牙設備,主要用了兩個手機,一個作為主設備,一個做為從設備。另外進行藍牙開發有一個調試利器。

主設備和從設備我分別創建了一個管理類。
主設備主要進行的操作如下:

  • 開始掃描設備
  • 停止掃描設備
  • 連接設備
  • 斷開連接設備
  • 發送數據

具體源碼如下:

#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 蓝牙开发实现文件传输的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。