在测试的时候,必须使用真机测试.模拟器不带该功能.
在测试该模块的时候,需要等待几十秒的时间.如果没有反应则在点击一下搜索设备按钮.
在这里,是以手机为
Central,小米手环为
Peripheral
.
需要注意的地方是:每个设备里面都有一些服务,而每个服务里面又对应一些特征.根据特征对其进行业务处理.
由于设备不问题,在服务和特征的这两版块,没法进行测试,扫描设备和连接设备已经OK.
详细代码
#import
"ViewController.h"
#import <CoreBluetooth/CoreBluetooth.h>
@interface ViewController ()< CBCentralManagerDelegate , CBPeripheralDelegate , UIAlertViewDelegate , UITableViewDataSource , UITableViewDelegate >
/** 中心者 */
@property ( nonatomic , strong ) CBCentralManager *manager;
/** 外设蓝牙 */
@property ( nonatomic , strong ) CBPeripheral *peripheral;
/** 外设蓝牙设备的特征 */
@property ( nonatomic , strong ) CBCharacteristic *characteristic;
@property ( nonatomic , strong ) NSMutableArray *peripheralArr;
@property ( weak , nonatomic ) IBOutlet UITableView *peripheralTableView;
@end
@implementation ViewController
-( CBCentralManager *)manager{
if (! _manager ){
_manager = [[ CBCentralManager alloc ] initWithDelegate : self queue : dispatch_get_main_queue ()];
}
return _manager ;
}
-( NSMutableArray *)peripheralArr{
if (! _peripheralArr ){
_peripheralArr = [ NSMutableArray array ];
}
return _peripheralArr ;
}
- ( void )viewDidLoad {
[ super viewDidLoad ];
self . peripheralTableView . delegate = self ;
}
// 扫描附近的蓝牙
- ( IBAction )searchPeripheral:( UIButton *)sender {
NSDictionary *dic = [ NSDictionary dictionaryWithObjectsAndKeys :[ NSNumber numberWithBool : false ], CBCentralManagerScanOptionAllowDuplicatesKey , nil ];
[ self . manager scanForPeripheralsWithServices : nil options :dic];
}
/**
* 中心者改变状态的时候会调用这个方法
*/
- ( void )centralManagerDidUpdateState:( CBCentralManager *)central{
NSString * state = nil ;
switch ([ self . manager state ])
{
case CBCentralManagerStateUnsupported :
state = @"The platform/hardware doesn't support Bluetooth Low Energy." ;
break ;
case CBCentralManagerStateUnauthorized :
state = @"The app is not authorized to use Bluetooth Low Energy." ;
break ;
case CBCentralManagerStatePoweredOff :
state = @"Bluetooth is currently powered off." ;
break ;
case CBCentralManagerStatePoweredOn :
state = @"work" ;
break ;
case CBCentralManagerStateUnknown :
state = @" 没找到 " ;
break ;
default :
state = @" 操作有误 " ;
#import <CoreBluetooth/CoreBluetooth.h>
@interface ViewController ()< CBCentralManagerDelegate , CBPeripheralDelegate , UIAlertViewDelegate , UITableViewDataSource , UITableViewDelegate >
/** 中心者 */
@property ( nonatomic , strong ) CBCentralManager *manager;
/** 外设蓝牙 */
@property ( nonatomic , strong ) CBPeripheral *peripheral;
/** 外设蓝牙设备的特征 */
@property ( nonatomic , strong ) CBCharacteristic *characteristic;
@property ( nonatomic , strong ) NSMutableArray *peripheralArr;
@property ( weak , nonatomic ) IBOutlet UITableView *peripheralTableView;
@end
@implementation ViewController
-( CBCentralManager *)manager{
if (! _manager ){
_manager = [[ CBCentralManager alloc ] initWithDelegate : self queue : dispatch_get_main_queue ()];
}
return _manager ;
}
-( NSMutableArray *)peripheralArr{
if (! _peripheralArr ){
_peripheralArr = [ NSMutableArray array ];
}
return _peripheralArr ;
}
- ( void )viewDidLoad {
[ super viewDidLoad ];
self . peripheralTableView . delegate = self ;
}
// 扫描附近的蓝牙
- ( IBAction )searchPeripheral:( UIButton *)sender {
NSDictionary *dic = [ NSDictionary dictionaryWithObjectsAndKeys :[ NSNumber numberWithBool : false ], CBCentralManagerScanOptionAllowDuplicatesKey , nil ];
[ self . manager scanForPeripheralsWithServices : nil options :dic];
}
/**
* 中心者改变状态的时候会调用这个方法
*/
- ( void )centralManagerDidUpdateState:( CBCentralManager *)central{
NSString * state = nil ;
switch ([ self . manager state ])
{
case CBCentralManagerStateUnsupported :
state = @"The platform/hardware doesn't support Bluetooth Low Energy." ;
break ;
case CBCentralManagerStateUnauthorized :
state = @"The app is not authorized to use Bluetooth Low Energy." ;
break ;
case CBCentralManagerStatePoweredOff :
state = @"Bluetooth is currently powered off." ;
break ;
case CBCentralManagerStatePoweredOn :
state = @"work" ;
break ;
case CBCentralManagerStateUnknown :
state = @" 没找到 " ;
break ;
default :
state = @" 操作有误 " ;
break
;
}
NSLog ( @"Central manager state: %@" , state);
}
NSLog ( @"Central manager state: %@" , state);
}
/**
* 发现一个蓝牙设备会调用这个方法
*
* @param central 中心者
* @param peripheral 发现的设备
* @param advertisementData 广告的信息
* @param RSSI 接受的强弱指数
*/
-( void )centralManager:( CBCentralManager *)central didDiscoverPeripheral:( CBPeripheral *)peripheral advertisementData:( NSDictionary *)advertisementData RSSI:( NSNumber *)RSSI{
// 判断信号的强弱
// if(RSSI.integerValue > -15){
// NSLog(@" 信号太强 , 好像不对 ");
// return ;
// }
// if(RSSI.integerValue < -35){
// NSLog(@" 信号太弱 , 好像不对 ");
// return ;
// }
[ self . peripheralArr addObject :peripheral];
[ self . peripheralTableView reloadData ];
if ([peripheral. name isEqualToString : @"MI" ]){
// 连接设备
[ self . manager connectPeripheral :peripheral options :[ NSDictionary dictionaryWithObject :[ NSNumber numberWithBool : YES ] forKey : CBConnectPeripheralOptionNotifyOnDisconnectionKey ]];
}
}
/**
* 当连接上某个蓝牙之后 ,CBCenteralManager 会通知这个方法
*/
-( void )centralManager:( CBCentralManager *)central didConnectPeripheral:( CBPeripheral *)peripheral{
NSLog ( @" 蓝牙设备连接上 " );
// 设置连接上的蓝牙的代理
peripheral. delegate = self ;
// 停止扫描
[ self . manager stopScan ];
// 查询蓝牙服务
[peripheral discoverServices : nil ];
}
/**
* 发现设备里面的服务会调用这个方法
*/
-( void )peripheral:( CBPeripheral *)peripheral didDiscoverServices:( NSError *)error{
if (error){
NSLog ( @"Discovered services for %@ with error: %@" , peripheral. name , [error localizedDescription ]);
return ;
}
// 匹配蓝牙
for ( CBService *service in peripheral. services ) {
NSLog ( @"Service found with UUID :%@" ,service. UUID );
if ([service. UUID isEqual :[ CBUUID UUIDWithString : @"FFE0" ]]){
// 搜索服务里面的特征
[peripheral discoverCharacteristics : nil forService :service];
}
}
}
/**
* 搜索服务里面的特征
*/
-( void )peripheral:( CBPeripheral *)peripheral didDiscoverCharacteristicsForService:( CBService *)service error:( NSError *)error{
if (error){
NSLog ( @"Discovered characteristics for %@ with error:%@" ,service. characteristics ,error. description );
return ;
}
for ( CBCharacteristic *characteristic in service. characteristics ) {
if ([characteristic. UUID isEqual :[ CBUUID UUIDWithString : @"FFE1" ]]){
self . peripheral = peripheral;
self . characteristic =characteristic;
}
}
}
// 发送数据给蓝牙设备
-( void )writeDataWithContenxt:( NSString *)str{
[ self . peripheral writeValue :[str dataUsingEncoding : CFStringConvertEncodingToNSStringEncoding ( kCFStringEncodingGB_18030_2000 )] forCharacteristic : self . characteristic type : CBCharacteristicWriteWithResponse ];
}
// 当设备有数据返回时,系统会调用这个方法
- ( void )peripheral:( CBPeripheral *)peripheral didUpdateValueForCharacteristic:( CBCharacteristic *)characteristic error:( NSError *)error{
NSData *data = characteristic. value ;
NSLog ( @"%@" ,[[ NSString alloc ] initWithData :data encoding : NSUTF8StringEncoding ]);
}
/**
* 断开连接
*/
-( void )disConnect{
if ( self . peripheral != nil ){
[ self . manager cancelPeripheralConnection : self . peripheral ];
self . peripheral = nil ;
self . characteristic = nil ;
}
}
/**
* 失去和外围设备的连接
*/
-( void )centralManager:( CBCentralManager *)central didDisconnectPeripheral:( CBPeripheral *)peripheral error:( NSError *)error{
// 重新连接
[ self . manager connectPeripheral :peripheral options : nil ];
}
* 发现一个蓝牙设备会调用这个方法
*
* @param central 中心者
* @param peripheral 发现的设备
* @param advertisementData 广告的信息
* @param RSSI 接受的强弱指数
*/
-( void )centralManager:( CBCentralManager *)central didDiscoverPeripheral:( CBPeripheral *)peripheral advertisementData:( NSDictionary *)advertisementData RSSI:( NSNumber *)RSSI{
// 判断信号的强弱
// if(RSSI.integerValue > -15){
// NSLog(@" 信号太强 , 好像不对 ");
// return ;
// }
// if(RSSI.integerValue < -35){
// NSLog(@" 信号太弱 , 好像不对 ");
// return ;
// }
[ self . peripheralArr addObject :peripheral];
[ self . peripheralTableView reloadData ];
if ([peripheral. name isEqualToString : @"MI" ]){
// 连接设备
[ self . manager connectPeripheral :peripheral options :[ NSDictionary dictionaryWithObject :[ NSNumber numberWithBool : YES ] forKey : CBConnectPeripheralOptionNotifyOnDisconnectionKey ]];
}
}
/**
* 当连接上某个蓝牙之后 ,CBCenteralManager 会通知这个方法
*/
-( void )centralManager:( CBCentralManager *)central didConnectPeripheral:( CBPeripheral *)peripheral{
NSLog ( @" 蓝牙设备连接上 " );
// 设置连接上的蓝牙的代理
peripheral. delegate = self ;
// 停止扫描
[ self . manager stopScan ];
// 查询蓝牙服务
[peripheral discoverServices : nil ];
}
/**
* 发现设备里面的服务会调用这个方法
*/
-( void )peripheral:( CBPeripheral *)peripheral didDiscoverServices:( NSError *)error{
if (error){
NSLog ( @"Discovered services for %@ with error: %@" , peripheral. name , [error localizedDescription ]);
return ;
}
// 匹配蓝牙
for ( CBService *service in peripheral. services ) {
NSLog ( @"Service found with UUID :%@" ,service. UUID );
if ([service. UUID isEqual :[ CBUUID UUIDWithString : @"FFE0" ]]){
// 搜索服务里面的特征
[peripheral discoverCharacteristics : nil forService :service];
}
}
}
/**
* 搜索服务里面的特征
*/
-( void )peripheral:( CBPeripheral *)peripheral didDiscoverCharacteristicsForService:( CBService *)service error:( NSError *)error{
if (error){
NSLog ( @"Discovered characteristics for %@ with error:%@" ,service. characteristics ,error. description );
return ;
}
for ( CBCharacteristic *characteristic in service. characteristics ) {
if ([characteristic. UUID isEqual :[ CBUUID UUIDWithString : @"FFE1" ]]){
self . peripheral = peripheral;
self . characteristic =characteristic;
}
}
}
// 发送数据给蓝牙设备
-( void )writeDataWithContenxt:( NSString *)str{
[ self . peripheral writeValue :[str dataUsingEncoding : CFStringConvertEncodingToNSStringEncoding ( kCFStringEncodingGB_18030_2000 )] forCharacteristic : self . characteristic type : CBCharacteristicWriteWithResponse ];
}
// 当设备有数据返回时,系统会调用这个方法
- ( void )peripheral:( CBPeripheral *)peripheral didUpdateValueForCharacteristic:( CBCharacteristic *)characteristic error:( NSError *)error{
NSData *data = characteristic. value ;
NSLog ( @"%@" ,[[ NSString alloc ] initWithData :data encoding : NSUTF8StringEncoding ]);
}
/**
* 断开连接
*/
-( void )disConnect{
if ( self . peripheral != nil ){
[ self . manager cancelPeripheralConnection : self . peripheral ];
self . peripheral = nil ;
self . characteristic = nil ;
}
}
/**
* 失去和外围设备的连接
*/
-( void )centralManager:( CBCentralManager *)central didDisconnectPeripheral:( CBPeripheral *)peripheral error:( NSError *)error{
// 重新连接
[ self . manager connectPeripheral :peripheral options : nil ];
}
#pragma mark --
表格的代理方法
-( NSInteger )tableView:( UITableView *)tableView numberOfRowsInSection:( NSInteger )section{
return self . peripheralArr . count ;
}
-( UITableViewCell *)tableView:( UITableView *)tableView cellForRowAtIndexPath:( NSIndexPath *)indexPath{
static NSString *ID = @"cell" ;
UITableViewCell *cell = [[ UITableViewCell alloc ] initWithStyle : UITableViewCellStyleDefault reuseIdentifier :ID];
NSLog ( @"%@" , self . peripheralArr [indexPath. row ]);
return cell;
}
-( NSInteger )tableView:( UITableView *)tableView numberOfRowsInSection:( NSInteger )section{
return self . peripheralArr . count ;
}
-( UITableViewCell *)tableView:( UITableView *)tableView cellForRowAtIndexPath:( NSIndexPath *)indexPath{
static NSString *ID = @"cell" ;
UITableViewCell *cell = [[ UITableViewCell alloc ] initWithStyle : UITableViewCellStyleDefault reuseIdentifier :ID];
NSLog ( @"%@" , self . peripheralArr [indexPath. row ]);
return cell;
}
@end