GJLightBlueTooth——一個(gè)輕量級(jí)的iOS藍(lán)牙開(kāi)發(fā)庫(kù)

從上家公司離職已經(jīng)快半年了,與藍(lán)牙打了一年的交道,從小白一個(gè)到略知一二。最近在整理上一家公司做的一些項(xiàng)目,突發(fā)奇想,自己封裝一個(gè)藍(lán)牙庫(kù),方便以后的使用。說(shuō)干就干,如果需要項(xiàng)目代碼,猛擊這里GJLightBlueTooth。如果有用,請(qǐng)賞顆小星星。

GJLightBlueTooth架構(gòu)

當(dāng)初為了不在一個(gè)類里面同時(shí)處理發(fā)送與接收邏輯,也本著對(duì)外封閉的原則,為了給使用庫(kù)的人一個(gè)簡(jiǎn)單的類,就設(shè)計(jì)了:

用戶 ——> GJLightBlueTooth ——> CoreBlueTooth ——> GJLightBlueTooth ——> 用戶

這樣的架構(gòu)

其中:

  • GJLightBlueTooth:相當(dāng)于一個(gè)中介,架起來(lái)自頁(yè)面用戶的指令和系統(tǒng)CoreBlueTooth交互的橋梁,這里的交互包括向藍(lán)牙設(shè)備發(fā)送指令和設(shè)置回調(diào)。
  • GJLBTCentralManager:所有與系統(tǒng)CoreBlueTooth的溝通都在這里進(jìn)行,這里將指令發(fā)出去,也在這里獲取回調(diào),通過(guò)block回傳。

另外,在Demo中,你還會(huì)看到MyBLETool這個(gè)類,這是為了將Demo項(xiàng)目中頁(yè)面與業(yè)務(wù)分離而單獨(dú)出來(lái)的一個(gè)類,可以理解為設(shè)備類。為了我們不需要在具體的頁(yè)面中去設(shè)置回傳的block。

使用

在創(chuàng)建頁(yè)面后,你應(yīng)該初始化GJLightBlueTooth藍(lán)牙工具:self.BLE = [[GJLightBlueTooth alloc] init]。

在獲取到Characteristic后,你應(yīng)該根據(jù)實(shí)際讀寫的Characteristic匹配出設(shè)備上的CBCharacteristic,保存在本地,用于后面的寫與讀。

[self.BLE setBlockWhenDiscoverCharacteristics:^(CBPeripheral *peripheral, CBService *service, NSError *error) {
        strongify(self);
        for (CBCharacteristic *cha in service.characteristics){
            if ([cha.UUID.UUIDString isEqualToString:CharacteristicUUIDWrite]){
                self.writeCharacter = cha;
            }
        }
        //[[NSNotificationCenter defaultCenter] postNotificationName:@"DiscoverCharacteristics" object:service];
    }];

掃描

[self.BLE scan]

停止掃描

[self.BLE stopScan]

連接設(shè)備

[self.BLE connectWithPeripheral:peri]

斷開(kāi)連接

[self.BLE cancelConnectWithPeripheral:peri]

讀取信號(hào)量

[self.BLE readRSSIWithPeriperal:peri]

發(fā)送數(shù)據(jù)

[self.BLE sendDataToPeriperal:peri WriteCharacteristic:self.writeCharacter Command:command NSEncoding:encoding]

這里針對(duì)現(xiàn)在很多公司提出需要手機(jī)與設(shè)備有心跳的要求,開(kāi)啟了一個(gè)線程隊(duì)列。該隊(duì)列設(shè)置能夠同時(shí)存在的指令數(shù)為3。

NSData *cmdData = [[NSString stringWithFormat:@"%@",command] dataUsingEncoding:encoding];
    
    NSOperation *opration = [NSBlockOperation blockOperationWithBlock:^{
        [peripheral writeValue:cmdData
            forCharacteristic:writeCharacteristics
                         type:CBCharacteristicWriteWithoutResponse];
        /*
         * you can set thread time interval.but the order while delay when there are a lot of orders.
         */
        //[NSThread sleepForTimeInterval:SleepTimeGap];
    }];
    
    [self.writeQueue addOperation:opration];

你也可以設(shè)置指令間隔時(shí)間,但是這樣會(huì)造成因心跳刷新過(guò)快造成的延遲發(fā)送。

注意

  1. 在新版本的iOS中,已經(jīng)不允許通過(guò)peripheral.RSSI來(lái)獲取設(shè)備的信號(hào)量,必須在用[peripheral readRSSI]后,使用回調(diào)來(lái)獲取。這就會(huì)造成在掃描到設(shè)備時(shí)候無(wú)法顯示信號(hào)量。所以專門創(chuàng)建了一個(gè)分類CBPeripheral+RSSI,利用Runtime來(lái)動(dòng)態(tài)給peripheral創(chuàng)建了一個(gè)rssi屬性。
char nameKey;

- (void)setRssi:(NSNumber *)rssi{
    objc_setAssociatedObject(self, &nameKey, rssi, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSNumber *)rssi{
    return objc_getAssociatedObject(self, &nameKey);
}
  1. 在MyBLETool中,需要設(shè)置GJLBTCentralManager回調(diào)流,這里為了防止循環(huán)引用,需要進(jìn)行weak-strong dance。
weakify(self);

[self.BLE setBlockWhenDiscoverCharacteristics:^(CBPeripheral *peripheral, CBService *service, NSError *error) {
        strongify(self);
        for (CBCharacteristic *cha in service.characteristics){
            if ([cha.UUID.UUIDString isEqualToString:CharacteristicUUIDWrite]){
                self.writeCharacter = cha;
            }
        }
        //[[NSNotificationCenter defaultCenter] postNotificationName:@"DiscoverCharacteristics" object:service];
    }];

最后是兩張demo的效果

DataSendVC.PNG

DataSendVC.PNG

如果需要項(xiàng)目代碼,猛擊這里GJLightBlueTooth。如果有用,請(qǐng)賞顆小星星。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容