蓝牙(CoreBluetooth)

在CoreBluetooth框架中,有两个主要的角色:外设和中心,整个框架都是围绕这两个主要角色设计的.

中心角色变成实现过程

1.设置CBCentralManager

2.发现并连接外设

3.发现服务

4.发现特征

5.预定特征通知

6.读取数据

[objc]view plaincopy

print?

#import 

#import 

#define TRANSFER_SERVICE_UUID           @"D63D44E5-E798-4EA5-A1C0-3F9EEEC2CDEB"

#define TRANSFER_CHARACTERISTIC_UUID    @"1652CAD2-6B0D-4D34-96A0-75058E606A98"

@interfaceViewController : UIViewController 

@property(strong,nonatomic) CBCentralManager      *centralManager;//CBCentralManager 是用来管理BLE的中心设备

@property(strong,nonatomic) CBPeripheral          *discoveredPeripheral;

@property(strong,nonatomic) NSMutableData         *data;

@property(weak,nonatomic) IBOutletUIActivityIndicatorView*activityIndicatorView;

@property(weak,nonatomic) IBOutletUILabel*scanLabel;

@property(weak,nonatomic) IBOutletUITextView*textView;

@end

[objc]view plaincopy

print?

@implementationViewController

- (void)viewDidLoad

{

[superviewDidLoad];

// 设置CBCentralManager

_centralManager = [[CBCentralManageralloc]initWithDelegate:selfqueue:nil];

// 保存接收数据

_data = [[NSMutableDataalloc]init];

}

- (void)viewWillDisappear:(BOOL)animated

{

[self.centralManagerstopScan];

[self.activityIndicatorViewstopAnimating];

NSLog(@"扫描停止");

[superviewWillDisappear:animated];

}

- (void)didReceiveMemoryWarning

{

[superdidReceiveMemoryWarning];

}

#pragma mark - Central Methods

//设置成功回调方法

- (void)centralManagerDidUpdateState:(CBCentralManager*)central

{

if(central.state!= CBCentralManagerStatePoweredOn) {

return;

}

//开始扫描

[selfscan];

}

/** 通过制定的128位的UUID,扫描外设

*/

- (void)scan

{

//扫描

[self.centralManagerscanForPeripheralsWithServices:@[[CBUUIDUUIDWithString:TRANSFER_SERVICE_UUID]]

options:@{ CBCentralManagerScanOptionAllowDuplicatesKey :@YES}];

[self.activityIndicatorViewstartAnimating];

self.scanLabel.hidden=NO;

NSLog(@"Scanning started");

}

/** 停止扫描

*/

- (void)stop

{

[self.centralManagerstopScan];

[self.activityIndicatorViewstopAnimating];

self.scanLabel.hidden=YES;

self.textView.text=@"";

NSLog(@"Scanning stoped");

}

//扫描成功调用此方法

- (void)centralManager:(CBCentralManager*)centraldidDiscoverPeripheral:(CBPeripheral*)peripheraladvertisementData:(NSDictionary*)advertisementDataRSSI:(NSNumber*)RSSI

{

// 过滤信号强度范围

if(RSSI.integerValue> -15) {

return;

}

if(RSSI.integerValue< -35) {

return;

}

NSLog(@"发现外设 %@ at %@", peripheral.name, RSSI);

if(self.discoveredPeripheral!= peripheral) {

self.discoveredPeripheral= peripheral;

NSLog(@"连接外设 %@", peripheral);

[self.centralManagerconnectPeripheral:peripheraloptions:nil];

}

}

- (void)centralManager:(CBCentralManager*)centraldidFailToConnectPeripheral:(CBPeripheral*)peripheralerror:(NSError*)error

{

NSLog(@"连接失败 %@. (%@)", peripheral, [errorlocalizedDescription]);

[selfcleanup];

}

//连接外设成功

- (void)centralManager:(CBCentralManager*)centraldidConnectPeripheral:(CBPeripheral*)peripheral

{

NSLog(@"外设已连接");

// Stop scanning

[selfstop];

NSLog(@"扫描停止");

[self.datasetLength:0];//重置data属性

peripheral.delegate=self;//设置外设对象的委托为self

[peripheraldiscoverServices:@[[CBUUIDUUIDWithString:TRANSFER_SERVICE_UUID]]];

}

/** 服务被发现

*/

//发现服务成功

- (void)peripheral:(CBPeripheral*)peripheraldidDiscoverServices:(NSError*)error

{

if(error) {

NSLog(@"Error discovering services: %@", [errorlocalizedDescription]);

[selfcleanup];

return;

}

// 发现特征

for(CBService*service in peripheral.services) {

[peripheraldiscoverCharacteristics:@[[CBUUIDUUIDWithString:TRANSFER_CHARACTERISTIC_UUID]]forService:service];

}

}

//发现特征成功

- (void)peripheral:(CBPeripheral*)peripheraldidDiscoverCharacteristicsForService:(CBService*)serviceerror:(NSError*)error

{

if(error) {

NSLog(@"发现特征错误: %@", [errorlocalizedDescription]);

[selfcleanup];

return;

}

for(CBCharacteristic*characteristic in service.characteristics) {

if([characteristic.UUIDisEqual:[CBUUIDUUIDWithString:TRANSFER_CHARACTERISTIC_UUID]]) {

// 预定特征

[peripheralsetNotifyValue:YESforCharacteristic:characteristic];

}

}

}

//特征状态发生变化

- (void)peripheral:(CBPeripheral*)peripheraldidUpdateValueForCharacteristic:(CBCharacteristic*)characteristicerror:(NSError*)error

{

if(error) {

NSLog(@"发现特征错误:: %@", [errorlocalizedDescription]);

return;

}

NSString*stringFromData = [[NSStringalloc]initWithData:characteristic.valueencoding:NSUTF8StringEncoding];

// 判断是否为数据结束

if([stringFromDataisEqualToString:@"EOM"]) {

// 显示数据

[self.textViewsetText:[[NSStringalloc]initWithData:self.dataencoding:NSUTF8StringEncoding]];

// 取消特征预定

[peripheralsetNotifyValue:NOforCharacteristic:characteristic];

// 断开外设

[self.centralManagercancelPeripheralConnection:peripheral];

}

// 接收数据追加到data属性中

[self.dataappendData:characteristic.value];

NSLog(@"Received: %@", stringFromData);

}

//特征值发生变化

- (void)peripheral:(CBPeripheral*)peripheraldidUpdateNotificationStateForCharacteristic:(CBCharacteristic*)characteristicerror:(NSError*)error

{

if(error) {

NSLog(@"特征通知状态变化错误: %@", error.localizedDescription);

}

// 如果没有特征传输过来则退出

if(![characteristic.UUIDisEqual:[CBUUIDUUIDWithString:TRANSFER_CHARACTERISTIC_UUID]]) {

return;

}

// 特征通知已经开始

if(characteristic.isNotifying) {

NSLog(@"特征通知已经开始 %@", characteristic);

}

// 特征通知已经停止

else{

NSLog(@"特征通知已经停止 %@", characteristic);

[self.centralManagercancelPeripheralConnection:peripheral];

}

}

//与外设连接断开时回调

- (void)centralManager:(CBCentralManager*)centraldidDisconnectPeripheral:(CBPeripheral*)peripheralerror:(NSError*)error

{

NSLog(@"外设已经断开");

self.discoveredPeripheral=nil;

//外设已经断开情况下,重新扫描

[selfscan];

}

/** 清除方法

*/

- (void)cleanup

{

// 如果没有连接则退出

if(!self.discoveredPeripheral.isConnected) {

return;

}

// 判断是否已经预定了特征

if(self.discoveredPeripheral.services!=nil) {

for(CBService*service inself.discoveredPeripheral.services) {

if(service.characteristics!=nil) {

for(CBCharacteristic*characteristic in service.characteristics) {

if([characteristic.UUIDisEqual:[CBUUIDUUIDWithString:TRANSFER_CHARACTERISTIC_UUID]]) {

if(characteristic.isNotifying) {

//停止接收特征通知

[self.discoveredPeripheralsetNotifyValue:NOforCharacteristic:characteristic];

//断开与外设连接

[self.centralManagercancelPeripheralConnection:self.discoveredPeripheral];

return;

}

}

}

}

}

}

//断开与外设连接

[self.centralManagercancelPeripheralConnection:self.discoveredPeripheral];

}

@end

外设角色编程实现过程

1.设置CBPeripheraManager

2.设置服务与特征

3.发布服务与特征

4.广播服务

5.发送数据

[objc]view plaincopy

print?

#import 

#import 

#define TRANSFER_SERVICE_UUID           @"D63D44E5-E798-4EA5-A1C0-3F9EEEC2CDEB"

#define TRANSFER_CHARACTERISTIC_UUID    @"1652CAD2-6B0D-4D34-96A0-75058E606A98"

#define NOTIFY_MTU      20

@interfaceViewController : UIViewController  

@property(strong,nonatomic) CBPeripheralManager       *peripheralManager;//用来管理BLE的外设设备

@property(strong,nonatomic) CBMutableCharacteristic   *transferCharacteristic;//特征类

@property(strong,nonatomic) NSData                    *dataToSend;

@property(nonatomic,readwrite) NSInteger              sendDataIndex;

@property(weak,nonatomic) IBOutletUITextView*textView;

- (IBAction)valueChanged:(id)sender;

@end

[objc]view plaincopy

print?

@implementationViewController

- (void)viewDidLoad

{

[superviewDidLoad];

//设置CBPeripheralManager

_peripheralManager = [[CBPeripheralManageralloc]initWithDelegate:selfqueue:nil];

}

- (void)viewWillDisappear:(BOOL)animated

{

[self.peripheralManagerstopAdvertising];

[superviewWillDisappear:animated];

}

#pragma mark - Peripheral Methods

//外设设置成功回调此方法

- (void)peripheralManagerDidUpdateState:(CBPeripheralManager*)peripheral

{

if(peripheral.state!= CBPeripheralManagerStatePoweredOn) {

return;

}

NSLog(@"BLE打开");

// 初始化特征

self.transferCharacteristic= [[CBMutableCharacteristicalloc]

initWithType:[CBUUIDUUIDWithString:TRANSFER_CHARACTERISTIC_UUID]

properties:CBCharacteristicPropertyNotify

value:nil

permissions:CBAttributePermissionsReadable];

// 初始化服务

CBMutableService*transferService = [[CBMutableServicealloc]

initWithType:[CBUUIDUUIDWithString:TRANSFER_SERVICE_UUID]

primary:YES];

// 添加特征到服务

transferService.characteristics= @[self.transferCharacteristic];

// 发布服务与特征

[self.peripheralManageraddService:transferService];

}

- (void)peripheralManager:(CBPeripheralManager*)peripheral

didAddService:(CBService*)service

error:(NSError*)error {

NSLog(@"添加服务");

if(error) {

NSLog(@"添加服务失败: %@", [errorlocalizedDescription]);

}

}

- (IBAction)valueChanged:(id)sender {

UISwitch* advertisingSwitch = (UISwitch*)sender;

if(advertisingSwitch.on) {

// 开始广播

[self.peripheralManagerstartAdvertising:@{ CBAdvertisementDataServiceUUIDsKey : @[[CBUUIDUUIDWithString:TRANSFER_SERVICE_UUID]] }];

}

else{

[self.peripheralManagerstopAdvertising];

}

}

//远程中心预定数据回调该方法

- (void)peripheralManager:(CBPeripheralManager*)peripheralcentral:(CBCentral*)centraldidSubscribeToCharacteristic:(CBCharacteristic*)characteristic

{

NSLog(@"中心已经预定了特征");

self.dataToSend= [self.textView.textdataUsingEncoding:NSUTF8StringEncoding];

self.sendDataIndex=0;

[selfsendData];

}

- (void)peripheralManager:(CBPeripheralManager*)peripheralcentral:(CBCentral*)centraldidUnsubscribeFromCharacteristic:(CBCharacteristic*)characteristic {

NSLog(@"中心没有从特征预定");

}

- (void)sendData {

//发送数据结束标识

staticBOOLsendingEOM =NO;

if(sendingEOM) {

BOOLdidSend = [self.peripheralManagerupdateValue:[@"EOM"dataUsingEncoding:NSUTF8StringEncoding]forCharacteristic:self.transferCharacteristiconSubscribedCentrals:nil];

if(didSend) {

sendingEOM =NO;

NSLog(@"Sent: EOM");

}

return;

}

if(self.sendDataIndex>=self.dataToSend.length) {

return;

}

BOOLdidSend =YES;

while(didSend) {

NSInteger amountToSend =self.dataToSend.length-self.sendDataIndex;

if(amountToSend > NOTIFY_MTU) amountToSend = NOTIFY_MTU;

NSData*chunk = [NSDatadataWithBytes:self.dataToSend.bytes+self.sendDataIndexlength:amountToSend];

//发送数据

didSend = [self.peripheralManagerupdateValue:chunkforCharacteristic:self.transferCharacteristiconSubscribedCentrals:nil];

if(!didSend) {

return;

}

NSString*stringFromData = [[NSStringalloc]initWithData:chunkencoding:NSUTF8StringEncoding];

NSLog(@"Sent: %@", stringFromData);

self.sendDataIndex+= amountToSend;

if(self.sendDataIndex>=self.dataToSend.length) {

sendingEOM =YES;

BOOLeomSent = [self.peripheralManagerupdateValue:[@"EOM"dataUsingEncoding:NSUTF8StringEncoding]forCharacteristic:self.transferCharacteristiconSubscribedCentrals:nil];

if(eomSent) {

sendingEOM =NO;

NSLog(@"Sent: EOM");

}

return;

}

}

}

//发送数据失败后(发送数据的队列已经满了)重新发送

- (void)peripheralManagerIsReadyToUpdateSubscribers:(CBPeripheralManager*)peripheral {

[selfsendData];

}

- (void)didReceiveMemoryWarning {

[superdidReceiveMemoryWarning];

}

@end

你可能感兴趣的:(蓝牙(CoreBluetooth))