因为公司做智能家居开发,有很多蓝牙的智能硬件。因此项目中经常需要和蓝牙打交道。为此为了提高开发效率,就把蓝牙的公共业务进行了封装。

本文将对封装的思路做一个简单的阐述。

 

首先我们需要一个头文件。在这个头文件中定义全局的宏,和结构体。看起来大概是这样的。

//包长相关的宏
#define MAX_PACK_LEN 2048
#define MAX_SEND_LEN 1024
#define MAX_SINGLE_PACKET_LEN 20

/* 新协议 命令字 begin */
/* 请求和应答协议版本命令字*/
#define REQUEST_PROTOCOL_VERSION                0X4001
#define RESPONSE_PROTOCOL_VERSION               0X0001

#define REQUEST_BIND_BLE_DEVICE                 0X4002      // 请求绑定设备
#define RESPONSE_BIND_BLE_DEVICE                0X0002      // 应答

#define REQUEST_SYNC_DATA                       0X4006      // 请求同步数据
#define RESPONSE_SYNC_DATA                      0X0006      // 应答

#define REQUEST_KEY_DATA                        0X4008      // 请求数据
#define RESPONSE_KEY_DATA                       0X0008      // 应答

#define REQUEST_DELETE_DATA                     0X4010      // 请求删除数据
#define RESPONSE_DELETE_DATA                    0X0010      // 应答

#define REQUEST_UPGRADE_FIREWARE                0X4012      // 请求升级固件
#define RESPONSE_UPGRADE_FIREWARE               0X0012      // 应答
/* 新协议 命令字 end */

/* 协议类型 */
#define PROTOCOL_TYPE_UPGRADE                   0x10        // 升级协议
#define PROTOCOL_TYPE_BUSINESS                  0x00        // 业务协议
#define PROTOCOL_TYPE_BIND                      0x02        // 绑定协议

//新的蓝牙协议包数据结构
typedef struct
{
    uint8_t         startflag;                  //起始标志      0XF2
    uint8_t         protocol_type;              //协议类型  升级协议:0x10 业务协议:0x00 绑定协议:0x02
    uint8_t         protocol_version;           //协议版本号
    uint8_t         reserved;                   //保留字节
    uint8_t         time[6];                    //协议时间  年以2010为基数往上累加
    uint8_t         timezone;                   //时区
    UInt16          frame_control;              //操作命令字
    uint16_t        body_length;                //数据长度
} Ble_Protocol_Head_New;

typedef struct{
    Ble_Protocol_Head_New*   head;
    uint8_t                 *body;              //包体
    uint16_t                 packet_fcs;        //FCS校验
}Ble_Protocol_Packet_New;

 

然后我们需要一个类来处理一些与具体业务无关的逻辑。比如错误处理,蓝牙数据收发,拆包和组包等这些。

我们姑且叫这个类为BleBaseApi吧。在我们的项目中这个只暴露了两个接口。看起来大概是这样的:

@class CLBLEBaseApi;
typedef NS_ENUM (NSUInteger, CLBLEState){
    CLBLEStateIdle,
    CLBLEStateSending,
    CLBLEStateReceiving,
};

typedef void (^BLEScanDiscoverPeripheralsCallback) (NSArray *peripherals);

@protocol CLBLEPacketHandle <NSObject>
-(NSInteger)receivedPacketDataLength;
-(NSInteger)totalPacketDataLength;

-(NSData*)singlePacketDataDeviceResponse;  //设备收到app的数据后,要给app回复一个数据,告诉app我已经收到数据

-(NSData*)singlePacketDataAppResponse;     //同理App也需要回复


-(NSData*)fetchCompletePacketData;        //完整的数据包

/**
 *  根据需要发送的数据包,做拆分,确定每一个包的数据内容
 *
 *  @return 单数数据包的内容
 */
-(NSData*)fetchSinglePacketData;         //拆包后的数据

/**
 *  解析收到的蓝牙数据
 *
 *  @param data  收到的数据
 *  @param error error信息
 *
 *  @return 如果解析完成,返回解析之后的值,如果解析失败返回空,error有值
 *  如果解析没有完成,返回空,error也是空
 */
-(NSData*)receiveAndParseData:(NSData*)data error:(NSError**)error;


-(id)apiManager:(CLBLEBaseApi*)manager reformData:(NSData*)data;
@end





@protocol CLBLEDataSource <NSObject>

@required

-(NSArray*)scanServiceArray;              //扫描到的服务       

-(NSString*)readSeriveID;                 //读取数据的服务ID

-(NSString*)readCharacteristicID;         //读取数据的特征ID

-(NSString*)writeSeriveID;              

-(NSString*)writeCharacteristicID;

-(LGPeripheral*)connectedPeripheral;      //连接到的外设

-(NSString *)broadName;                   //广播名

@end

typedef void (^BLEProgressiveDownLoadBlock) (NSInteger totalBytesRead, NSInteger totalBytesExpected);

typedef void (^BLESuccessBlock) (NSData *data);

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

typedef void (^BleStateBlock)(CBCentralManagerState state);

@interface CLBLEBaseApi : NSObject

@property (nonatomic,weak) NSObject<CLBLEDataSource>* child;

@property (nonatomic,assign) CLBLEState state;

@property (nonatomic,assign) BOOL bleIsReady;


-(void)setProgressiveBlock:(BLEProgressiveDownLoadBlock)progressBlock;
-(void)sendBLEDataWithDataPacketProtocol:(id<CLBLEPacketHandle>)packetDelegate
                                 Success:(BLESuccessBlock)successBlock
                                    fail:(BLEFailBlock)failBlock;

 其中 sendBLEDataWithDataPacketProtocol 方法处理蓝牙数据的发送接收,它的实现大概是这样子的

-(void)sendBLEDataWithDataPacketProtocol:(id<CLBLEPacketHandle>)packetDelegate
                                 Success:(BLESuccessBlock)successBlock
                                    fail:(BLEFailBlock)failBlock{
    if (self.state!= CLBLEStateIdle) {
        NSError* error=[NSError errorWithDomain:kCLBLEManagerErrorDomain code:kBLEBusyErrorCode userInfo:@{@"message":kBLEBusyErrorCodeErrorMessage}];
        failBlock(error);
        return;
    }
    self.child=(id <CLBLEDataSource>)self;

    if (!self.child.connectedPeripheral) {
        NSError* error=[NSError errorWithDomain:kCLBLEManagerErrorDomain code:kBLEObjErrorCode userInfo:@{@"message":kBLEObjErrorCodeErrorMessage}];
        failBlock(error);
        return;
    }
    if (self.child.connectedPeripheral.cbPeripheral.state!=CBPeripheralStateConnected) {
        //NSError* error=[NSError errorWithDomain:kCLBLEManagerErrorDomain code:kBLECommunConnectErrorCode userInfo:@{@"message":@"设备没有连接,发个毛啊!"}];
        NSError* error=[NSError errorWithDomain:kCLBLEManagerErrorDomain code:kBLECommunConnectErrorCode userInfo:@{@"message":kBLECommunConnectErrorCodeErrorMessage}];
        failBlock(error);
        return;
    }
    self.dataPacketHandleDelegate=packetDelegate;
    [self sendBLEDataWithData:[self.dataPacketHandleDelegate fetchCompletePacketData]
                      Success:successBlock
                         fail:failBlock];
}

 

在BleBaseApi中声明了一个protocal用来获取数据包的长度以及各种数据包等,所以我们创建一个名为BleProtocal的类来负责这个事情

typedef NSData* (^fetchSinglePacketDataBlock)();
typedef NSData* (^receiveAndParseDataBlock)(NSData*data,NSError**error);
typedef id    (^reformDataBlock)(NSData*data);

@interface CLBLEBaseProtocol : NSObject<CLBLEPacketHandle>

@property(nonatomic,strong)NSData* singleDeviceResponsePacketData;
@property(nonatomic,strong)NSData* singleAppResponsePacketData;

@property(nonatomic,strong)NSData* packetData;
@property(nonatomic,copy)fetchSinglePacketDataBlock SinglePacketDataBlock;
@property(nonatomic,copy)receiveAndParseDataBlock receiveAndParseDataBlock;
@property(nonatomic,copy)reformDataBlock reformDataBlock;
@property(nonatomic,assign) NSInteger singlePacketTotalSend;
@property(nonatomic,assign) NSInteger  packetDataLength;
@property(nonatomic,assign) NSInteger receiveBufferLength;
@property(nonatomic,strong) NSMutableData* mutableReceiveData;

这是BleProtocal的头文件,诸如 singleDeviceResponsePacketData ,packetData 这些数据都是外界传进来的。这个文件的实现大概是这样的

-(receiveAndParseDataBlock)receiveAndParseDataBlock
{
     __weak  CLBLEBaseProtocol * weakself = self;
    receiveAndParseDataBlock block = ^NSData*(NSData*data,NSError**error){

        if (!data) {
            *error=[NSError errorWithDomain:@"BLEReceiveDataHelper" code:01 userInfo:@{@"errorInfo":@"解析数据不能传空值"}];
            return nil;

        }
        if (data.length<=0) {
            *error=[NSError errorWithDomain:@"BLEReceiveDataHelper" code:01 userInfo:@{@"errorInfo":@"解析数据不能传空值"}];
            return nil;
        }


        if (weakself.receiveBufferLength==0) {
            uint8_t startFlag=0;
            [data getBytes:&startFlag length:1];
            if (startFlag!=0xf2) {
                [self clear];
                *error=[NSError errorWithDomain:@"BLEReceiveDataHelper" code:02 userInfo:@{@"errorInfo":@"起始不是0xf2"}];
                return nil;
            }
        }
        if (!weakself.mutableReceiveData) {
            weakself.mutableReceiveData=[[NSMutableData alloc] initWithCapacity:0];
        }
        [weakself.mutableReceiveData appendData:data];
        weakself.receiveBufferLength+=data.length;

        if (weakself.receiveBufferLength>=sizeof(Ble_Protocol_Head_T)) {

            Ble_Protocol_Head_T bleProtocolHeaderT={0};

            int offset = (int)((size_t)&(bleProtocolHeaderT.body_length)-(size_t)&bleProtocolHeaderT);

            typeof (weakself.packetDataLength) length;
            [[weakself.mutableReceiveData subdataWithRange:NSMakeRange(offset, 2)] getBytes:&length length:2];

            weakself.packetDataLength = length;
            weakself.packetDataLength=htons(weakself.packetDataLength);
            weakself.packetDataLength=sizeof(Ble_Protocol_Head_T)+1+weakself.packetDataLength;

            if (weakself.receiveBufferLength>=weakself.packetDataLength) {

                NSData* resultPacketData=[weakself.mutableReceiveData subdataWithRange:NSMakeRange(0, weakself.packetDataLength)];

                uint8_t endFlag=0;
                [[weakself.mutableReceiveData subdataWithRange:NSMakeRange(weakself.packetDataLength-1, 1)] getBytes:&endFlag length:1];

                if (endFlag==0xf3) {
                    if (weakself.receiveBufferLength==weakself.packetDataLength) {
//                        [weakself clear];
                    }
                    *error=nil;
                    //接收完成
                    return resultPacketData;
                }
                else{
                    *error=[NSError errorWithDomain:@"BLEReceiveDataHelper" code:02 userInfo:@{@"errorInfo":@"结束标志不是0xf3"}];
                    return nil;
                }
            }
        }
        //接收 ing
        *error=nil;
        return nil;
    };
    return [block copy];
}

-(fetchSinglePacketDataBlock)SinglePacketDataBlock
{

  __weak  CLBLEBaseProtocol * weakself = self;
    fetchSinglePacketDataBlock block = ^NSData*(){


        if ( weakself.singlePacketTotalSend >= weakself.packetData.length)
        {
            return nil;
        }
        int cur_send = ((self.packetData.length - _singlePacketTotalSend) > MAX_SINGLE_PACKET_LEN)? MAX_SINGLE_PACKET_LEN: (int)(self.packetData.length - self.singlePacketTotalSend);
        NSData* singleData=[self.packetData subdataWithRange:NSMakeRange(self.singlePacketTotalSend, cur_send)];
        self.singlePacketTotalSend += cur_send;

        return singleData;

    };

    return [block copy];
}

#pragma mark- BLEDataReformer
-(id)apiManager:(CLBLEBaseApi *)manager reformData:(NSData *)data
{
    return self.reformDataBlock?self.reformDataBlock(data):nil;
}

#pragma mark- CLBLEPacketHandle
-(NSInteger)receivedPacketDataLength
{
    return self.receiveBufferLength;
}
-(NSInteger)totalPacketDataLength
{
    return self.packetDataLength;
}
-(NSData*)singlePacketDataDeviceResponse
{
    return self.singleDeviceResponsePacketData;
}
-(NSData*)singlePacketDataAppResponse
{
    return self.singleAppResponsePacketData;
}
/**
 *  一个完整包的数据内容
 *
 *  @return 完整数据包的内容
 */
-(NSData*)fetchCompletePacketData
{
    return self.packetData;
}

/**
 *  根据需要发送的数据包,做拆分,确定每一个包的数据内容
 *
 *  @return 单数数据包的内容
 */
-(NSData*)fetchSinglePacketData
{
    return self.SinglePacketDataBlock?self.SinglePacketDataBlock():nil;
}

/**
 *  解析收到的蓝牙数据
 *
 *  @param data  收到的数据
 *  @param error error信息
 *
 *  @return 如果解析完成,返回解析之后的值,如果解析失败返回空,error有值
 *  如果解析没有完成,返回空,error也是空
 */
-(NSData*)receiveAndParseData:(NSData*)data error:(NSError**)error
{
    return self.receiveAndParseDataBlock?self.receiveAndParseDataBlock(data,error):nil;
}

因为继承了<CLBLEPacketHandle> 所以实现了他的代理,通过这样将需要的数据包和数据长度传递给BleBaseApi。

 

现在假设我们有一个智能床垫是蓝牙设备。我们会创建两个类分别继承自BleBaseApi和BleProtocal

我们先看看BLEMattressProtocol。它的头文件大概如下:

@interface BLEMattressProtocol :CLBLEBaseProtocol

uint8_t ble_currentTimeOffset();

void ble_gmtTimeString(uint8_t* timeValue);

void ble_gmtTimeString_new(uint8_t* timeValue);
void Init_Ble_Protocol_Head(uint8_t *packetArray,short comdNo,uint16_t dataLength,uint8_t* uniqueID,NSString *deviceVersion);
void Init_Ble_Protocol_Head_New(uint8_t *packetArray,short comdNo,uint16_t dataLength,uint8_t* uniqueID);
//获取统计数据的数据包
+(BLEMattressProtocol*)getRequestStatisticalPacketData:(NSString*)uinqueIDString;

//通知设备清除统计数据的数据包
+(BLEMattressProtocol*)getDeleteStatisticalPacketData:(NSString*)uinqueIDString;


/**
 *  获取实时数据数据包
 *
 *  @param uinqueIDString 唯一ID
 *
 *  @return 返回获取实时数据的数据包
 */
+(BLEMattressProtocol*)getRequestRealTimePacketData:(NSString*)uinqueIDString;

/**
 *  确认蓝牙升级的数据包
 *
 *  @param uinqueIDString 唯一ID
 *
 *  @return 返回获取蓝牙升级的数据包
 */
+(BLEMattressProtocol *)getRequestConfirmUpgrade:(NSString *)uinqueIDString;


@end

再看看实现文件:

//获取统计数据的数据包
+(BLEMattressProtocol*)getRequestStatisticalPacketData:(NSString*)uinqueIDString{
    uint8_t packetHead[sizeof(Ble_Protocol_Head_T)]={0};
//    uint8_t uinqueID[6]={0};
    uint8_t* uinqueID=(uint8_t*)[uinqueIDString UTF8String];

    Init_Ble_Protocol_Head(packetHead, REQUEST_GET_DATA_COMMAND, 0,uinqueID,nil);

    NSMutableData* packetData=[[NSMutableData alloc] initWithCapacity:0];
    NSData* packetHeadData=[NSData dataWithBytes:packetHead length:sizeof(Ble_Protocol_Head_T)];
    [packetData appendData:packetHeadData];

    uint8_t endCommand=BLE_PROTOCOL_END_FLAG;
    [packetData appendBytes:&endCommand length:1];

    BLEMattressProtocol* obj= [[self alloc] init];
    uint8_t byte[]={0};

//    obj.singleAppResponsePacketData = [NSData dataWithBytes:byte length:1];
    obj.singleDeviceResponsePacketData = [NSData dataWithBytes:byte length:1];  //这里就是给BleProtocal里的那些属性赋值
    obj.packetData = packetData;
    return obj;

//    return packetData;
}

 

我们再看看 MattressBLEManagerApi。下面是他的头文件。

@interface MattressBLEManagerApi : CLBLEBaseApi<CLBLEDataSource>

@property (nonatomic,strong) LGPeripheral* currentPeripheral;
@property (nonatomic,strong) NSString* currentBroadName;
@property (nonatomic,assign) BOOL BLEIsPowerOn;
//固件升级时候版本号,如1.9.0
@property (nonatomic,assign) NSString* DeviceUpgradeVersion;
-(void)fetchHistoryDataWithSuccessBlock:(void(^)(NSData* data))success
                              FailBlock:(void(^)(NSError* error))fail;

-(void)fetchRealTimeDataSuccessBlock:(void(^)(NSData* data))success
                           FailBlock:(void(^)(NSError* error))fail;

-(void)fetchRealTimeDataWithInterVal:(NSTimeInterval)interval
                            WithTimes:(NSTimeInterval)times
                            SuccessBlock:(void(^)(NSData* data))success
                           FailBlock:(void(^)(NSError* error))fail;


-(void)fetchBLEHandShakeSuccessBlock:(void(^)(NSData* data))success
                           FailBlock:(void(^)(NSError* error))fail;


//还没有调用
-(void)deleteStatisticalDataWithSuccessBlock:(void(^)(NSData* data))success
                                   FailBlock:(void(^)(NSError* error))fail;

-(void)fetchProtocolVersionSuccessBlock:(void(^)(NSData* data))success
                              FailBlock:(void(^)(NSError* error))fail;

-(void)stopFetchRealTimeData;
-(void)resumeFetchRealTimeData;
-(void)suspendFetchRealTimeData;

@end

 

 MattressBLEManagerApi继承了 CLBLEBaseApi<CLBLEDataSource>。通过实现 CLBLEDataSource里的代理提供了广播名,服务ID,特征ID等数据。

这个类里面我们就开始了与具体业务逻辑相关的操作了。下面看看他的实现文件。

-(void)fetchHistoryDataWithSuccessBlock:(void(^)(NSData* data))success
                              FailBlock:(void(^)(NSError* error))fail{
    
    NSLog(@"fetchHistoryDataWithSuccessBlock0");
    NSLog(@"CLBLEStateIdle == %d",CLBLEStateIdle);
    NSLog(@"self.state == %d",self.state);
    
    //不相等说明蓝牙繁忙
    if ( self.state != CLBLEStateIdle) {
        NSError* error=[NSError errorWithDomain:kCLBLEManagerErrorDomain code:kBLEBusyErrorCode userInfo:@{@"message":kBLEBusyErrorCodeErrorMessage}];;
        fail(error);
        return ;
    }
    __weak MattressBLEManagerApi* weakSelf=self;
    if (self.connectedPeripheral.cbPeripheral.state==CBPeripheralStateConnected) {
        sendRealTimeData =[BLEMattressProtocol getRequestStatisticalPacketData:self.uniqueID];
        [self sendBLEDataWithDataPacketProtocol:sendRealTimeData
                                        Success:^(NSData *data) {
                                            /*历史数据比较简单,获取历史数据,上传到服务器,然后通知设备,清除数据。
                                             然后告诉外面结果就说成功了,
                                             业务接口自己去服务器拉取数据,整个上传数据流程完毕。
                                             */
                                            success(data);
                                            NSLog(@"data is %@",data);
                                        } fail:^(NSError *error) {
                                            NSLog(@"error is %@",error);
                                            fail(error);
                                        }];
    }
    else{
        NSLog(@"fetchHistoryDataWithSuccessBlock11");
        self.currentPeripheral=nil;
        [[CLBLEManager sharedInstance] conntectPeripheralWithBLEDataSource:self
                                                           withResultBlock:^(LGPeripheral *peripheral, NSError *error) {
                                                               NSLog(@"fetchHistoryDataWithSuccessBlock1");
                       if (error) {
                           fail(error);
                       }
                       else{
                           weakSelf.currentPeripheral=peripheral;
                           sendRealTimeData =[BLEMattressProtocol getRequestStatisticalPacketData:self.uniqueID];
                           [weakSelf sendBLEDataWithDataPacketProtocol:sendRealTimeData
                                                           Success:^(NSData *data) {
                                                               /*历史数据比较简单,获取历史数据,上传到服务器,然后通知设备,清除数据。
                                                                然后告诉外面结果就说成功了,
                                                                业务接口自己去服务器拉取数据,整个上传数据流程完毕。
                                                                */
                                                               success(data);
                                                               NSLog(@"data is %@",data);
                                                           } fail:^(NSError *error) {
                                                               NSLog(@"error is %@",error);
                                                               fail(error);
                                                           }];
                       }
        }];
    }

}

这一段代码是获取历史数据的接口。

 

除开上面那些,我们还需要对蓝牙的扫描,连接,探索,读写数据,断开等操作进行封装。所以我们创建了CLBLEManager类。他来管理这些操作。

头文件大概如下:

@protocol CLBLEManagerDelegate <NSObject>

-(void)scanAllPeripherals:(NSArray *)allLGPeripherals;

@end

@interface CLBLEManager : NSObject

@property (strong, nonatomic) LGPeripheral  *currentLGPeripheral;
@property (strong, nonatomic) CBCentralManager *manager;
+(CLBLEManager *)sharedInstance;


//初始化蓝牙并设置读取数据的回调,自动扫描,如果扫描设备名字broadName为空,则扫描所有设备并返回列表,如果broadName不为空则返回连接上的蓝牙设备
-(void)scanbleWithObject:(id<CLBLEDataSource>)child
         withScanTimeOut:(NSInteger)timeOut;
     //scanPeripheralBlock:(void (^)(NSArray *peripherals,NSError *error))scanPeripheralBlock;
//连接蓝牙
//-(void)conntectPeripheral:(LGPeripheral *)peripheral withResultBlock:(void(^)(NSError *error))connectResultBlock;

-(void)conntectPeripheralWithBLEDataSource:(id<CLBLEDataSource>)child
                           withResultBlock:(void(^)(LGPeripheral* peripheral,NSError *error))connectResultBlock;
//OAD空中升级的时候必须先扫描后连接
-(void)oadConntectPeripheralWithBLEDataSource:(id<CLBLEDataSource>)child
                           withResultBlock:(void(^)(LGPeripheral* peripheral,NSError *error))connectResultBlock;

//发送数据
-(void)sendData:(NSData *)data peripheral:(LGPeripheral *)peripheral;
//设置Notify
-(void)setNotify:(LGPeripheral *)peripheral WithCBUUID:(CBUUID *)sCBUUID cCBUUID:(CBUUID *)cCBUUID withResultBlock:(void(^)(NSError *error))resultBlock withResultBlock:(void(^)(NSData *data,NSError *error))readDataBlock;
//断开蓝牙
-(void)disconntectPeripheral:(LGPeripheral *)peripheral withResultBlock:(void(^)(NSError *error))aCallback;

 

实现文件大体如下:

-(void)scanbleWithObject:(id<CLBLEDataSource>)child
         withScanTimeOut:(NSInteger)timeOut
{
    
    self.broadName=nil;
    if ([child respondsToSelector:@selector(broadName)]) {
        self.broadName=[child broadName];
    }
    if ([child connectedPeripheral].name) {
        self.broadName=child.connectedPeripheral.name;
    }
    self.scanServiceArray=child.scanServiceArray;
    self.readServiceUUID=child.readSeriveID;
    self.readCharacteristic=child.readCharacteristicID;
    self.writeServiceUUID=child.writeSeriveID;
    self.writeCharacteristic=child.writeCharacteristicID;
    if(self.readServiceUUID.length==0||self.readCharacteristic.length==0||self.writeServiceUUID.length==0||self.writeCharacteristic.length==0)
    {
        [self.multicasetDelegate scanAllPeripherals:nil];
        return;
    }
    __weak CLBLEManager *weakself=self;
    if([LGCentralManager sharedInstance].centralReady)
    {
        [weakself scanWithTimeout:timeOut scanFinishBlock:^(NSArray *peripherals)
        {
            [weakself.multicasetDelegate scanAllPeripherals:peripherals];
        }];
        
    }
    self.hasConnectedPeripherals=[[NSMutableArray alloc]init];
    self.retrievePeripheralsWithIdentifiers=[[NSMutableArray alloc]init];
    self.scanPeripheralsCallback=nil;
    // Custom initialization
    
    [LGCentralManager sharedInstance].updateStateBlock =^(CBCentralManagerState state)
    {
        if (state == CBCentralManagerStatePoweredOn)
        {
            if (![LGCentralManager sharedInstance].isScanning)
            {
                [weakself scanWithTimeout:timeOut scanFinishBlock:^(NSArray *peripherals)
                {
                    
                    [weakself.multicasetDelegate scanAllPeripherals:peripherals];
                }];
            }
        }
    };
    
}

 

好了,到这里就结束了。以上就是我们在项目中对蓝牙业务进行封装的一个大致思路。

分类:

技术点:

相关文章: