美文网首页
IOS BLE 开发

IOS BLE 开发

作者: 蜂子阁先生 | 来源:发表于2018-10-22 17:11 被阅读68次

一.关键词

  • 中央设备:中央设备用于管理外设,一个中央设备可以同时连接管理多个外设。
  • 中心设备管理(CBCentralManager):管理外设的工具,提供扫描连接外设等方法。
  • 外设(CBPeripheral):如蓝牙耳机,音响,打印机等,外设主动广播数据(advertisementData)描述其设备的基本信息,如此设备是什么,叫什么,提供什么样的服务(CBService)(类似于电台广播,不管是否有用户,都会广播信号以描述其电台信息)。
  • 外设管理(CBPeripheralManager):管理外设,给外设添加服务
  • 服务(CBService):一个外设至少有一个服务,一个服务包含多个特征,每个服务由唯一的一个UUID确定。
  • 特征(CBCharacteristic):设备间通讯的最小单元或者说是一个通讯通道,每个特征由唯一的一个UUID确定。
  • 特征值:特征存储的数据。
  • 特征属性:用于描述特征的权限,如读,写等,以下是oc特征属性的枚举:
typedef NS_OPTIONS(NSUInteger, CBCharacteristicProperties) {
    CBCharacteristicPropertyBroadcast                                               = 0x01,
    CBCharacteristicPropertyRead                                                    = 0x02,
    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
};
  • 广播数据(advertisementData):用于描述外设基本信息

二.工作流程

外设工作流程

  1. 建立外设管理(CBPeripheralManager):需要实现CBPeripheralManagerDelegate协议。
  2. 新建添加服务(CBMutableService)设置服务特征(CBCharacteristic),后续通过特征通讯。
  3. 广播服务。

中心设备工作流程

  1. 建立中心设备管理(CBCentralManager):需实现CBCentralManagerDelegate,CBPeripheralDelegate协议
  2. 扫描外设。
  3. 连接外设。
  4. 扫描外设服务。
  5. 选择使用外设服务。
  6. 获取服务特征(即获取了通讯通道)。
  7. 选择使用特征进行通讯。

通讯流程

三.上代码

外设

//
//  BLECBPeripheral.h
//  BLE
//
//  Created by chenguibang on 2017/3/15.
//  Copyright © 2017年 chenguibang. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>
@interface BLECBPeripheral : NSObject<CBPeripheralManagerDelegate>
@property(nonatomic,strong) CBPeripheralManager *peripheralManager;

+(id)shared;

-(void)setup;

-(void)addSe;
-(void)adv;
@end

//
//  BLECBPeripheral.m
//  BLE
//
//  Created by chenguibang on 2017/3/15.
//  Copyright © 2017年 chenguibang. All rights reserved.
//

#import "BLECBPeripheral.h"
#define kPeripheralName @"Kenshin Cui's Device" //外围设备名称
#define kServiceUUID @"C4FB2349-72FE-4CA2-94D6-1F3CB16331EE" //服务的UUID
#define kCharacteristicUUID @"6A3E4B28-522D-4B3B-82A9-D5E2004534FC" //特征的
@implementation BLECBPeripheral

+(id)shared{
    static dispatch_once_t onceToken;
    static BLECBPeripheral *per = nil;
    dispatch_once(&onceToken, ^{
        per = [[BLECBPeripheral alloc]init];
    });
    return per;
    
}

-(void)setup{
    self.peripheralManager = [[CBPeripheralManager alloc]initWithDelegate:self queue:nil];
}


-(void)addSe{
    CBUUID *characteristicUUID=[CBUUID UUIDWithString:kCharacteristicUUID];
    CBMutableCharacteristic *characteristicM=[[CBMutableCharacteristic alloc]initWithType:characteristicUUID properties:CBCharacteristicPropertyNotify|CBCharacteristicPropertyWriteWithoutResponse|CBCharacteristicPropertyRead value:nil permissions:CBAttributePermissionsReadable|CBAttributePermissionsWriteable|CBAttributePermissionsReadEncryptionRequired|CBAttributePermissionsWriteEncryptionRequired];
    CBUUID *serviceUUID=[CBUUID UUIDWithString:kServiceUUID];
    //创建服务
    CBMutableService *serviceM=[[CBMutableService alloc]initWithType:serviceUUID primary:YES];
    //设置服务的特征
    [serviceM setCharacteristics:@[characteristicM]];
    
    /*将服务添加到外围设备*/
    [self.peripheralManager addService:serviceM];
}


-(void)adv{
    //添加服务后开始广播
    NSDictionary *dic=@{CBAdvertisementDataLocalNameKey:kPeripheralName};//广播设置
    [self.peripheralManager startAdvertising:dic];//开始广播
}

-(void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral{
    
    switch (peripheral.state) {
        case CBManagerStatePoweredOn:
            NSLog(@"BLE已打开.");
        
            break;
            
        default:
            NSLog(@"BLE已打开.异常");
            break;
    }
}

-(void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error{
    NSLog(@"添加服务成功");
}

-(void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(NSError *)error{
    NSLog(@"广播成功");
}

-(void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic{
    NSLog(@"有服务订阅特征值");
}

-(void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic{
    NSLog(@"有服务取消订阅特征值");
}

-(void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request{
    NSLog(@"收到读请求");
}

-(void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray<CBATTRequest *> *)requests{
    NSLog(@"收到写请求");
    
}

@end


中央设备

//
//  BLETool.h
//  BLEOCChat
//
//  Created by chenguibang on 2017/3/14.
//  Copyright © 2017年 chenguibang. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>

typedef void(^ErrorBlcok)(NSError* error);

@interface BLETool : NSObject<CBCentralManagerDelegate,CBPeripheralDelegate>
@property(nonatomic,strong)CBCentralManager *centerManager;
@property(nonatomic,strong)NSMutableArray<CBPeripheral*> *peripherals;
@property(nonatomic,strong)NSMutableArray<CBService*> *sevices;
@property(nonatomic,strong)NSMutableArray<CBCharacteristic *>*characters;
@property(nonatomic,copy)ErrorBlcok errorBlcok;
+(id)shared;
-(void)setup;
-(void)scanfPer:(NSUInteger)timeout;
-(void)stopScanf;
-(void)connectTo:(CBPeripheral*)peripheral reuslt:(void(^)())result;
-(void)disconnect:(CBPeripheral*)peripheral;
-(void)discoverServicesFor:(CBPeripheral*)peripheral;
-(void)discoverCharactersFor:(CBService *)service In:(CBPeripheral*)peripheral;


-(void)write:(CBPeripheral*)peripheral forCharacteristic:(CBCharacteristic *)characteristic value:(NSData *)data;
@end


//
//  BLETool.m
//  BLEOCChat
//
//  Created by chenguibang on 2017/3/14.
//  Copyright © 2017年 chenguibang. All rights reserved.
//

#import "BLETool.h"


#define findMeServiceUUID             [CBUUID UUIDWithString:@"1802"]
#define genericAccessServiceUUID      [CBUUID UUIDWithString:@"1800"]
#define linkLossServiceUUID           [CBUUID UUIDWithString:@"1803"]
#define deviceNameCharacteristicUUID  [CBUUID UUIDWithString:@"2A00"]
#define alertLevelCharacteristicUUID  [CBUUID UUIDWithString:@"2A06"]
#define BT_ALERT_LEVEL_NONE 0
#define BT_LEVEL_MILD 1
#define BT_ALERT_LEVEL_HIGH 2
#define BT_ALERT_LEVEL_RESERVED(LVL) LVL

@interface BLETool(){
//    CBCentralManager *centerManager;
    
}

@end

@implementation BLETool


+(id)shared{
    static dispatch_once_t onceToken;
    static BLETool *tool;
    dispatch_once(&onceToken, ^{
        tool = [[BLETool alloc]init];
        [tool setup];
    });
    return tool;
}
-(void)setup{
    
//    1.建立中心管理
    self.centerManager = [[CBCentralManager alloc]initWithDelegate:self queue:nil];
    self.centerManager.delegate  = self;//设置代理
    self.peripherals = [NSMutableArray array];
    self.sevices = [NSMutableArray array];
    self.characters = [NSMutableArray array];


}

-(void)scanfPer:(NSUInteger)timeout{
    

    if (self.centerManager.isScanning) {
        [[self mutableArrayValueForKey:@"peripherals"]removeAllObjects];
        [self.centerManager stopScan];
    }
//    2.扫描外设
    [self.centerManager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey:[NSNumber numberWithInt:1],CBCentralManagerOptionShowPowerAlertKey:[NSNumber numberWithInt:1]}];
}
-(void)stopScanf{
    [self.centerManager stopScan];
}

-(void)connectTo:(CBPeripheral*)peripheral reuslt:(void(^)())result{
    if (self.centerManager.isScanning) {
        [self.centerManager stopScan];
    }
    //    3.连接外设
    if (peripheral.state != CBPeripheralStateDisconnected) {
        NSLog(@"该设备暂时不能连接");
        
        self.errorBlcok([NSError errorWithDomain:NSURLErrorDomain code:1 userInfo:@{@"msg":@"外设暂时状态不可连接"}]);
    
    }else{
        [self.centerManager connectPeripheral:peripheral options:nil];
    }
    
    
}
-(void)disconnect:(CBPeripheral *)peripheral{
    [self.centerManager cancelPeripheralConnection:peripheral];
}

-(void)discoverServicesFor:(CBPeripheral*)peripheral{
    NSMutableArray *sevices = [self mutableArrayValueForKeyPath:@"sevices"];
    [sevices removeAllObjects];
    peripheral.delegate = self;
    [peripheral discoverServices:nil];
}



-(void)write:(CBPeripheral*)peripheral forCharacteristic:(CBCharacteristic *)characteristic value:(NSData *)data{
    [peripheral setNotifyValue:YES forCharacteristic:characteristic];
    [peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];
}

-(void)centralManagerDidUpdateState:(CBCentralManager *)central{
    
    switch (central.state) {
        case CBManagerStateUnknown:
            
            break;
        case CBManagerStateResetting:
            
            break;
            
        case CBManagerStateUnsupported:
            
            break;
            
        case CBManagerStateUnauthorized:
            
            break;
            
        case CBManagerStatePoweredOff:
            
            break;
            
        case CBManagerStatePoweredOn:
//            [central scanForPeripheralsWithServices:nil options:nil];
            break;
        default:
            break;
    }
    
    
    NSLog(@"scanState  :  %ld \n" , (long)central.state);
}

-(void)discoverCharactersFor:(CBService *)service In:(CBPeripheral*)peripheral;{
    NSMutableArray *characters = [self mutableArrayValueForKeyPath:@"characters"];
    [characters removeAllObjects];
    [peripheral discoverCharacteristics:nil forService:service];
}



//advertisementData 外设主动发送的广播数据  RSSI 信号强度单位是dbm
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI{
    
    NSMutableArray *peripherals = [self mutableArrayValueForKeyPath:@"peripherals"];
    if (![self.peripherals containsObject:peripheral]) {
        
        [peripherals addObject:peripheral];
//        [[self mutableArrayValueForKeyPath:@"peripherals"] addObject:peripheral];
        
    }else{
      NSUInteger index =  [peripherals indexOfObject:peripheral];
        [peripherals replaceObjectAtIndex:index withObject:peripheral];
        
//        [[self mutableArrayValueForKeyPath:@"peripherals"] replaceObjectAtIndex:[self.peripherals indexOfObject:peripheral] withObject:peripheral];
        
    }
    NSLog(@"scan DisconnectPeripherals:  %@ \n",self.peripherals);
//  NSLog(@"uuid : %@\n",peripheral.identifier.UUIDString);


}

-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
    NSLog(@"连接成功");
    self.errorBlcok([NSError errorWithDomain:NSURLErrorDomain code:9999 userInfo:@{@"msg":@"连接成功"}]);

}
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error{
    self.errorBlcok([NSError errorWithDomain:NSURLErrorDomain code:9999 userInfo:@{@"msg":@"连接失败"}]);
}


-(void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
    
}

-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
     NSLog(@"发现服务");

    if (!error) {
        NSMutableArray *sevices = [self mutableArrayValueForKeyPath:@"sevices"];
        [sevices addObjectsFromArray:peripheral.services];
        for (CBService *service in peripheral.services) {
            NSLog(@"%@",service.UUID);
            [peripheral discoverCharacteristics:nil forService:service];
        }
    }else{
        self.errorBlcok([NSError errorWithDomain:NSURLErrorDomain code:9999 userInfo:@{@"msg":@"查找失败"}]);
    }
    
    
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(nullable NSError *)error{
    NSMutableArray *characters = [self mutableArrayValueForKeyPath:@"characters"];
    [characters addObjectsFromArray:service.characteristics];
}


-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForDescriptor:(CBDescriptor *)descriptor error:(NSError *)error{
    
}

-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
    
}

-(void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
    
}

@end


相关文章

  • iOS BLE Scan

    iOS扫描BLE设备的方法 iOS在使用CoreBluetooth框架进行BLE开发时,通常作为中心设备(Mast...

  • 12月第三周

    iOS-BLE蓝牙开发持续更新 - IOS - 伯乐在线 ReactiveCocoa 中 RACSignal 所有...

  • ios蓝牙参考

    参考文章:iOS中的蓝牙开发iOS-BLE蓝牙开发demo 官网 转载 CenteralManager学习笔记

  • iOS开发之BLE(二)——外设连接与断开

    在 iOS开发之BLE(一)——理论知识 一文中,主要对iOS开发中BLE的基本理论知识进行了介绍,本文以中心模式...

  • iOS-蓝牙开发Mark

    iOS蓝牙的开发专题[http://liuyanwei.jumppo.com/2015/07/17/ios-BLE...

  • iOS开发之BLE(二)——外设连接与断开

    在iOS开发之BLE(一)——理论知识一文中,主要对iOS开发中BLE的基本理论知识进行了介绍,本文以中心模式为例...

  • CoreBluetooth

    iOS-BLE蓝牙开发持续更新 - 简书 蓝牙打印小票 一个第三方 IOS BLE4.0蓝牙和外设连接和收发数据的...

  • macOS-BLE蓝牙4.0开发

    macOS-BLE蓝牙4.0开发 !!!中心模式 !!! macOS的BLE程序代码和iOS差不多,只需要修改一些...

  • iOS BLE开发

    简介 BLE(Bluetooth Low Energy),低功耗蓝牙,使用2.4GHz无线电频率。从蓝牙4.0开始...

  • iOS BLE开发

    经过一段长期的学习,从开始猥琐发育到最后最后终于来真泰瑞。 倒入头文件 BLE蓝牙使用的是coreBluetoot...

网友评论

      本文标题:IOS BLE 开发

      本文链接:https://www.haomeiwen.com/subject/iuejnttx.html