CoreBluetooth中,須要用到的類和協議(完整導圖):html
藍牙分類中心端和外設端(完整導圖)。數組
中心端(接收端)app
1 .建立中心端控制器(CBCentralManager)
2 .掃描設備(Discover)
3 .鏈接 (Connect)
4 .獲取Service和Characteristicide
- 掃描Service (一個service中包含一個或多個Characteristic)
- 獲取Service中Characteristic
- 獲取Characteristic的值
5 . 數據交互(explore and interact)測試
- 訂閱Characteristic的通知
6 . 斷開連接ui
外設端(發送端)atom
- 建立Peripheral管理對象
- 建立Service和Characteristic樹
- 發送廣告
- 處理讀寫請求和訂閱
藍牙狀態 spa
typedef NS_ENUM(NSInteger, CBManagerState) { CBManagerStateUnknown = 0, CBManagerStateResetting, CBManagerStateUnsupported, //不支持 CBManagerStateUnauthorized, //未受權 CBManagerStatePoweredOff, //關閉 CBManagerStatePoweredOn, //藍牙打開狀態 } NS_ENUM_AVAILABLE(NA, 10_0);
鏈接狀態命令行
/*! * @enum CBPeripheralState * * @discussion Represents the current connection state of a CBPeripheral. * */ typedef NS_ENUM(NSInteger, CBPeripheralState) { CBPeripheralStateDisconnected = 0, CBPeripheralStateConnecting, CBPeripheralStateConnected, CBPeripheralStateDisconnecting NS_AVAILABLE(NA, 9_0), } NS_AVAILABLE(NA, 7_0);
CBCentralManagerDelegate 3d
@required // 更新CentralManager狀態,參數central就是當前的Manager。 - (void)centralManagerDidUpdateState:(CBCentralManager *)central; @optional // 藍牙狀態的保存和恢復,進入後臺和從新啓動有關 - (void)centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary<NSString *, id> *)dict; //掃描外部設備 - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *, id> *)advertisementData RSSI:(NSNumber *)RSSI; //與外設完成鏈接 - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral; //鏈接失敗 - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error; //斷開鏈接 - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error;
CBPeripheralDelegate
@optional //peripheral更新 - (void)peripheralDidUpdateName:(CBPeripheral *)peripheral NS_AVAILABLE(NA, 6_0); //服務更新時觸發 - (void)peripheral:(CBPeripheral *)peripheral didModifyServices:(NSArray<CBService *> *)invalidatedServices NS_AVAILABLE(NA, 7_0); //更新RSSI,過期用下一代替 - (void)peripheralDidUpdateRSSI:(CBPeripheral *)peripheral error:(nullable NSError *)error NS_DEPRECATED(NA, NA, 5_0, 8_0); // RSSI值 - (void)peripheral:(CBPeripheral *)peripheral didReadRSSI:(NSNumber *)RSSI error:(nullable NSError *)error NS_AVAILABLE(NA, 8_0); //發現服務 - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(nullable NSError *)error; //發現嵌套服務 - (void)peripheral:(CBPeripheral *)peripheral didDiscoverIncludedServicesForService:(CBService *)service error:(nullable NSError *)error; //發現服務中的Characteristic - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(nullable NSError *)error; //更新Characteristic - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error; - (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error; - (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error; - (void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error; - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForDescriptor:(CBDescriptor *)descriptor error:(nullable NSError *)error; - (void)peripheral:(CBPeripheral *)peripheral didWriteValueForDescriptor:(CBDescriptor *)descriptor error:(nullable NSError *)error;
CBPeripheralManagerDelegate
@required //相似CBCentralManager - (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral; @optional - (void)peripheralManager:(CBPeripheralManager *)peripheral willRestoreState:(NSDictionary<NSString *, id> *)dict; //開始廣播 - (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(nullable NSError *)error; //添加服務 - (void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(nullable NSError *)error; //訂閱 - (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic; //未訂閱 - (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic; //接收讀取請求 - (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request; //接收寫入請求 - (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray<CBATTRequest *> *)requests; //更新訂閱 - (void)peripheralManagerIsReadyToUpdateSubscribers:(CBPeripheralManager *)peripheral;
從上面瞭解了藍牙開發的基本流程和API結構,那下面咱們一塊兒看看中心端的開發步驟。
//建立CentralManager - (void)startUpCentralManager { _centralManager = [[CBCentralManager alloc] initWithDelegate: self queue: nil]; _peripherals = [NSMutableArray array]; //用於存放掃描的外設 }
建立CentralManager會調用Delegate方法:
#pragma mark - CBCentralManagerDelegate // 實現: 確保支持BL和有效的Central設備 - (void)centralManagerDidUpdateState:(CBCentralManager *)central { switch (central.state) { case CBManagerStatePoweredOn: //只有此狀態下才能夠進行掃描設備 [self scan]; break; case CBManagerStateUnknown: break; case CBManagerStateResetting: break; case CBManagerStateUnsupported: break; case CBManagerStateUnauthorized: break; case CBManagerStatePoweredOff: break; default: break; } }
- (void)scan { [self.centralManager scanForPeripheralsWithServices: nil options: nil]; NSLog(@"Scanning started"); }
serviceUUIDs: 是一個CBUUID類型的數組,每一個CBUUID表明一個service的UUID。使用這個參數能夠限制掃描內容,若是設置爲nil,則表示搜索所有外設。
options: 定義掃描 ,字典。
- CBCentralManagerScanOptionAllowDuplicatesKey : 布爾值,無重複過濾的掃描。默認是NO。若是設置爲YES,對電池有不利影響。
- CBCentralManagerScanOptionSolicitedServiceUUIDsKey 想要掃描的Service UUIDs數組(NSArray)。
另外,在
bluetooth-central
後臺模式下,option將被忽略。這個問題後面會詳細講解。
當啓動掃描後,每次掃描到一個外設就會調用delegate方法:centralManager: didDiscoverPeripheral: advertisementData: RSSI:
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *, id> *)advertisementData RSSI:(NSNumber *)RSSI { NSLog(@"%@", peripheral.name); //查找到設備並持有它,不然不會保存 [self.peripherals addObject: peripheral]; }
- peripheral : 掃描到的設備
- advertisementData: 字典包含全部的廣告數據
- RSSI:received signal strength indicator,單位分貝。表示信號強度。
到這一步咱們掃描到外部設備,那接下來就是創建鏈接了。
經過掃描,咱們發現了目標外設,接下來創建鏈接。
- (void)startUpConnect { [self.centralManager connectPeripheral: self.peripheral options: nil]; }
self.peripheral : 目標外設
options :字典,用來定製鏈接行爲
- CBConnectPeripheralOptionNotifyOnConnectionKey
- CBConnectPeripheralOptionNotifyOnDisconnectionKey
- CBConnectPeripheralOptionNotifyOnNotificationKey
進行鏈接一般會出現兩種狀況:成功、失敗。
鏈接成功
本地鏈接成功,會調用方法:
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral { NSLog(@"連接設備名稱爲:%@", peripheral.name); // 設置代理 peripheral.delegate = self; //發現服務 [peripheral discoverServices: nil]; }
鏈接失敗
//連接失敗 - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error { NSLog(@"鏈接名稱:%@ 失敗,緣由:%@", peripheral.name, error.localizedDescription); }
另外,既然能夠創建鏈接,那麼確定能夠斷開鏈接。
斷開鏈接
//斷開連接 - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error { NSLog(@"與外設斷開連接:%@, %@", peripheral.name, error.localizedDescription); }
若是斷開鏈接不是由
cancelPeripheralConnection:
發起的,error會給出詳細信息。須要注意的是,當斷開鏈接,全部的services, characteristics和Characteristic descriptions都是無效的。
建立鏈接成功後,在delegate方法中
// 設置代理 peripheral.delegate = self; //發現服務 [peripheral discoverServices: nil];
能夠經過
CBUUID
指定的服務。
CBPeripheralDelegate
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error { if (error) { NSLog(@"發現服務錯誤:%@", error.localizedDescription); return; } // 一個外設會發送多個服務 for (CBService *service in peripheral.services) { //掃描每一個service的Characteristic,經過Characteristic的UUID來指定查找那個Characteristic。 [peripheral discoverCharacteristics: nil forService: service]; } }
注:一個外設包含多個Service,能夠經過Service的UUID來區分。一個Service包含多個Characteristic,經過Characteristic的UUID來區分。
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error { if (error) { NSLog(@"發現特徵錯誤:%@", error.localizedDescription); return; } for (CBCharacteristic *characteristic in service.characteristics) { //直接讀取Characteristic值,此時調用peripheral: didUpdateValueForCharacteristic: error: [peripheral readValueForCharacteristic: characteristic]; //另外一種狀況,訂閱特徵。此時調用 peripheral: didUpdateNotificationStateForCharacteristic: error: [peripheral setNotifyValue:YES forCharacteristic: characteristic]; } }
//給指定的特徵設置通知 - (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error { if (error) { NSLog(@"Error changing notification state : %@", error.localizedDescription); } if (![characteristic.UUID isEqual:[CBUUID UUIDWithString:@""]]) { return; } if (characteristic.isNotifying) { NSLog(@"Notification began on :%@", characteristic); } else { NSLog(@"Notification stoped on : %@ Disconnecting", characteristic); [self.centralManager cancelPeripheralConnection: peripheral]; } }
//readValueCharacteristic時調用 - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error { //打印出characteristic的UUID和值 //!注意,value的類型是NSData,具體開發時,會根據外設協議制定的方式去解析數據 NSLog(@"特性ID::%@ 值:%@",characteristic.UUID, characteristic.value); }
- (void)writeValue { NSData *data = [@"Test" dataUsingEncoding:NSUTF8StringEncoding]; [self.peripheral writeValue: data forCharacteristic: self.characteristic type: CBCharacteristicWriteWithResponse]; }
發送數據
- value: 寫入值
- characteristic : 被寫入的特徵
- type: 寫入類型,是否有應答
typedef NS_ENUM(NSInteger, CBCharacteristicWriteType) { CBCharacteristicWriteWithResponse = 0, CBCharacteristicWriteWithoutResponse, };當type爲CBCharacteristicWriteWithResponse時,調用delegate方法:
peripheral: didWriteValueForCharacteristic: error:
。
//建立PeripheralManager - (void)startUpPeripheralManager { _peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue: nil]; } //惟一@required方法 - (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral { switch (peripheral.state) { case CBManagerStatePoweredOn: // 建立服務和特徵 [self buildService]; break; case CBManagerStateUnknown : break; case CBManagerStateResetting: break; case CBManagerStateUnsupported: break; case CBManagerStateUnauthorized: break; case CBManagerStatePoweredOff: break; default: break; } }
- (void)buildService { //建立Characteristic self.transferCharacteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_UUID] properties:CBCharacteristicPropertyNotify value: nil permissions:CBAttributePermissionsReadable]; //建立服務 CBMutableService *transferService = [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID] primary:YES]; //將特徵添加到服務中 transferService.characteristics = @[self.transferCharacteristic]; //將服務添加到PeripheralManager中,調用delegate方法: peripheralManager: didAddService: error: [self.peripheralManager addService: transferService]; }
建立Characteristic
- UUID : 惟一標識
- properties:屬性
- value : 設置nil, 動態設置。
- permission : 權限
屬性
typedef NS_OPTIONS(NSUInteger, CBCharacteristicProperties) { //特徵值能夠使用特徵描述廣播 CBCharacteristicPropertyBroadcast = 0x01, //特徵值能夠被讀取,經過readValueForCharacteristic: 來讀取 CBCharacteristicPropertyRead = 0x02, // 能夠被讀寫,經過writeValue: forCharacteristic: type: 寫入特徵值,無應答標識寫入成功。 CBCharacteristicPropertyWriteWithoutResponse = 0x04, // 能夠被寫入,有應答標識寫入成功 CBCharacteristicPropertyWrite = 0x08, //容許通知特徵值,無應答表示接收 CBCharacteristicPropertyNotify = 0x10, //容許通知特徵值,有應答表示接收 CBCharacteristicPropertyIndicate = 0x20, CBCharacteristicPropertyAuthenticatedSignedWrites = 0x40, CBCharacteristicPropertyExtendedProperties = 0x80, //只有信任的設備接收特徵值通知 CBCharacteristicPropertyNotifyEncryptionRequired NS_ENUM_AVAILABLE(NA, 6_0) = 0x100, CBCharacteristicPropertyIndicateEncryptionRequired NS_ENUM_AVAILABLE(NA, 6_0) = 0x200 };
屬性特徵,能夠組合使用。
權限
typedef NS_OPTIONS(NSUInteger, CBAttributePermissions) { // 可讀 CBAttributePermissionsReadable = 0x01, // 可寫 CBAttributePermissionsWriteable = 0x02, // 信任可讀 CBAttributePermissionsReadEncryptionRequired = 0x04, // 信任可寫 CBAttributePermissionsWriteEncryptionRequired = 0x08 } NS_ENUM_AVAILABLE(NA, 6_0);
UUID : 惟一標識
isPrimary:YES:主服務;NO:次服務添加特徵到characteristics數據
調用delegate方法: peripheralManager: didAddService: error:
//開始廣告 - (void)startAdvertise { [self.peripheralManager startAdvertising:@{CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]]}]; } //中止廣告 - (void)stopAdvertise { [self.peripheralManager stopAdvertising]; }
開始廣告
advertisementData: 可選字典,包含想要廣告的數據。兩種類型:
- CBAdvertisementDataLocalNameKey :對應名稱
- CBAdvertisementDataServiceUUIDsKey : 對應UUID
調用delegate方法:peripheralManagerDidStartAdvertising: error:
- (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic { NSLog(@"當前Characteristic被訂閱"); }
當characteristic配置爲notify或indicate,將喚起次方法。
- (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic { NSLog(@"Central unsubscribed from characteristic"); }
當central移除特徵的notification/indications時調用,取消訂閱回調。
- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request { } - (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray<CBATTRequest *> *)requests { }
當接收到中心端的讀寫請求式,會觸發這個方法。
在該方法被調用時,能夠在方法內經過PeripheralManager調用:respondToRequest: withResult:
來響應中心端的讀寫請求。
plist文件中,設置UIBackgroundModes:
- bluetooth-central
- bluetooth-peripheral
當設置爲此模式,容許APP切入後臺後還能進行藍牙服務。依然能進行掃描,鏈接,交互數據等。
進入後臺CBCentralManagerScanOptionAllowDuplicatesKey
掃描被忽略。
當設置爲此模式,容許APP進行讀寫,鏈接中心端等。CBAdvertisementDataLocalNameKey
被忽略,本地外設名不在廣播。
PeripheralManager
#import "LQPeripheralManager.h" #import <CoreBluetooth/CoreBluetooth.h> static NSString *const ServiceUUID1 = @"FFF0"; static NSString *const notifyCharacteristicUUID = @"FFF1"; static NSString *const readwriteCharacteristicUUID = @"FFF2"; static NSString *const ServiceUUID2 = @"FFE0"; static NSString *const readCharacteristicUUID = @"FFE1"; static NSString *const LocalNameKey = @"Owenli"; @interface LQPeripheralManager ()<CBPeripheralManagerDelegate> @property (nonatomic, strong) CBPeripheralManager *peripheralManager; @property (nonatomic, strong) NSTimer *timer; @property (nonatomic, assign) NSInteger index; @end @implementation LQPeripheralManager + (instancetype)shareInstance { static LQPeripheralManager *peripheral; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ peripheral = [[self alloc] init]; }); return peripheral; } - (instancetype)init { if (self = [super init]) { _peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil]; _index = 0; } return self; } /** * @Description 初始化化UUID和服務信息 */ - (void)setup { //characteristic字段描述 CBUUID *cbuuidCharacteristicUserDescriptionStringUUID = [CBUUID UUIDWithString:CBUUIDCharacteristicUserDescriptionString]; /* 能夠通知的Characteristic properities : CBCharacteristicPropertyNotify permissions : CBAttributePermissionsReadable */ CBMutableCharacteristic *notifyCharacteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:notifyCharacteristicUUID] properties:CBCharacteristicPropertyNotify value:nil permissions:CBAttributePermissionsReadable]; /* 可讀寫的characteristic prperitise: CBCharacteristicPropertyWrite | CBCharacteristicPropertyRead permisssions : CBAttributePermissionsReadable | CBAttributePermisssionWriteable */ CBMutableCharacteristic * readwriteCharacteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:readwriteCharacteristicUUID] properties:CBCharacteristicPropertyWrite | CBCharacteristicPropertyRead value:nil permissions:CBAttributePermissionsReadable | CBAttributePermissionsWriteable]; // 設置descriptor CBMutableDescriptor *readwriteCharacteristicDescription1 = [[CBMutableDescriptor alloc] initWithType:cbuuidCharacteristicUserDescriptionStringUUID value:@"name"]; [readwriteCharacteristic setDescriptors:@[readwriteCharacteristicDescription1]]; /* 只讀Characteristic properties: CBCharacteristicPropertyRead permisssions: CBAttributePermissionsReadable */ CBMutableCharacteristic *readCharacteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:readCharacteristicUUID] properties:CBCharacteristicPropertyRead value:nil permissions:CBAttributePermissionsReadable]; // 第一個Service CBMutableService *service1 = [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:ServiceUUID1] primary:YES]; [service1 setCharacteristics:@[notifyCharacteristic, readwriteCharacteristic]]; //第二個Service CBMutableService *service2 = [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:ServiceUUID2] primary:YES]; [service2 setCharacteristics:@[readCharacteristic]]; //添加到periperal此時會調用,peripheralManager: didAddService: error: [self.peripheralManager addService:service2]; [self.peripheralManager addService:service1]; } #pragma mark - PeripherManagerDelegate //檢測藍牙狀態, - (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral { switch (peripheral.state) { case CBManagerStatePoweredOn: //初始化 [self setup]; break; case CBManagerStatePoweredOff: NSLog(@"powered off"); break; default: break; } } - (void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error { if (error) { NSLog(@"%@", error.localizedDescription); return; } //添加服務後,開始廣播 //自動回調: peripheralManagerDidStartAdvertising: error: [self.peripheralManager startAdvertising:@{ CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:ServiceUUID1], [CBUUID UUIDWithString:ServiceUUID2]], CBAdvertisementDataLocalNameKey : LocalNameKey }]; } //通知發送廣播 - (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(NSError *)error { if (error) { NSLog(@"%@", error.localizedDescription); } NSLog(@"start advert"); } - (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic { NSLog(@"subscribe data of : %@", characteristic.UUID); //分配定時任務 self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(sendData:) userInfo:characteristic repeats:YES]; } - (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic { NSLog(@"unsubscrible: %@", characteristic.UUID); [self.timer invalidate]; } - (void)sendData:(NSTimer *)timer { CBMutableCharacteristic *characteristic = timer.userInfo; if ([self.peripheralManager updateValue:[[NSString stringWithFormat:@"send data : %ld", _index] dataUsingEncoding: NSUTF8StringEncoding] forCharacteristic:characteristic onSubscribedCentrals:nil]) { NSLog(@"發送成功"); _index ++; } else { NSLog(@"發送數據錯誤"); } } //中心設備讀取請求 - (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request { NSLog(@"readRequest"); if (request.characteristic.properties & CBCharacteristicPropertyRead) { NSData *data = [[NSString stringWithFormat:@"by characteristic request"] dataUsingEncoding:NSUTF8StringEncoding]; [request setValue:data]; //對請求做出成功響應 [self.peripheralManager respondToRequest:request withResult:CBATTErrorSuccess]; } else { [self.peripheralManager respondToRequest:request withResult:CBATTErrorWriteNotPermitted]; } } //寫入請求 - (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray<CBATTRequest *> *)requests { NSLog(@"writeRequest"); CBATTRequest *request = requests.firstObject; if (request.characteristic.properties & CBCharacteristicPropertyWrite) { CBMutableCharacteristic *charateristic = (CBMutableCharacteristic *)request.characteristic; charateristic.value = request.value; NSLog(@"receive data :%@", [[NSString alloc] initWithData:charateristic.value encoding:NSUTF8StringEncoding]); [self.peripheralManager respondToRequest:request withResult:CBATTErrorSuccess]; } else { [self.peripheralManager respondToRequest:request withResult:CBATTErrorWriteNotPermitted]; } } - (void)peripheralManagerIsReadyToUpdateSubscribers:(CBPeripheralManager *)peripheral { NSLog(@"peripheralManagerIsReadyToUpdateSubscribers"); } @end
使用LighBlue測試外設端
命令行生成UUID
方法:uuidgen
。
Mac測試軟件:LighBlue,能夠用來測試iOS端外設。