iOS中藍(lán)牙與打印機(jī)連接使用

公司最近幫一家物流公司做一個員工使用的APP,需要用到藍(lán)牙去連接設(shè)備打印運(yùn)單信息久又,下面記錄一些在對接藍(lán)牙打印時(shí)候遇到的問題巫延,也總結(jié)一下其他技術(shù)文章中的一些知識點(diǎn)供大家參考效五,網(wǎng)上也有別人做好的第三方BabyBluetooth,這個第三方也可以在我們找的幾種設(shè)備上正常打印炉峰,同學(xué)們可以去看看這個怎么使用畏妖,有問題的地方希望大家提出來。

一疼阔、關(guān)于藍(lán)牙開發(fā)的一些重要的理論概念:

1戒劫、服務(wù)(services):藍(lán)牙外設(shè)對外廣播的時(shí)候一定會有一個服務(wù),有些時(shí)候也可以是有多個服務(wù)婆廊,服務(wù)下面包含一些特性迅细,服務(wù)可以理解成一個模塊的窗口;
2淘邻、特征(characteristic):特征存在于服務(wù)下面的茵典,一個服務(wù)下面可以有多個特征,特征可以理解成具體實(shí)現(xiàn)功能的窗口宾舅,一般的特性都會有value统阿,也就是特征值,是特征和外界交互的最小單位贴浙;
3砂吞、UUID:藍(lán)牙上的唯一標(biāo)示符,為了區(qū)分不同服務(wù)和特征崎溃,就用UUID來表示蜻直。

二、藍(lán)牙連接的主要步驟

 1袁串、創(chuàng)建一個CBCentralManager實(shí)例來進(jìn)行藍(lán)牙管理概而;

 2、使用CBCentralManager對象搜索掃描外圍設(shè)備囱修;

 3赎瑰、連接外圍設(shè)備;

 4破镰、獲得外圍設(shè)備的服務(wù)餐曼;

 5、獲得服務(wù)的特征鲜漩;

 6源譬、從外圍設(shè)備讀取數(shù)據(jù);

 7孕似、給外圍設(shè)備發(fā)送(寫入)數(shù)據(jù)踩娘。

三、藍(lán)牙連接和數(shù)據(jù)讀寫的具體步驟

1喉祭、導(dǎo)入蘋果系統(tǒng)藍(lán)牙框架<CoreBluetooth/CoreBluetooth.h>

2养渴、遵循兩個藍(lán)牙框架相關(guān)的協(xié)議<CBCentralManagerDelegate,CBPeripheralDelegate>

3雷绢、新建兩個實(shí)例屬性,一個特征屬性
@property (nonatomic, strong) CBCentralManager *centralManager; //中心管理者
@property (nonatomic, strong) CBPeripheral *peripheral; //連接到的外設(shè)
@property (nonatomic, strong) CBCharacteristic *characteristic; //特征

4理卑、實(shí)例化CBCentralManager對象進(jìn)行藍(lán)牙管理
self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue()]; //創(chuàng)建實(shí)例進(jìn)行藍(lán)牙管理

在實(shí)例化該對象之后翘紊,就會觸發(fā)下面這個必須實(shí)現(xiàn)的代理方法,否則在實(shí)例化之后會閃退藐唠,在該方法里面也可以獲取到藍(lán)牙的狀態(tài)霞溪,可以在此處提示用戶去打開藍(lán)牙

- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
    NSString * state = nil;
    switch ([central 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:
        default:
            ;
    }
}

客戶的需求里面有下次進(jìn)入該界面自動連接設(shè)備的功能,開始做的時(shí)候是實(shí)例化之后馬上開始連接之前的設(shè)備中捆,但是總是連接不上。實(shí)際上等這個回調(diào)函數(shù)調(diào)用之后就可以連接了坊饶,包括去搜索也是一樣泄伪,如果大家操作相關(guān)功能之后沒有效果,可能是這個函數(shù)還沒調(diào)用的原因匿级,怎么連接之前的設(shè)備一會會講到蟋滴。

5.掃描藍(lán)牙設(shè)備(根據(jù)SERVICE_UUID來掃描外設(shè),如果不設(shè)置則掃描所有藍(lán)牙設(shè)備)

[central scanForPeripheralsWithServices:nil options:nil];

執(zhí)行掃描動作之后痘绎,如果掃描到外設(shè)了津函,就會自動回調(diào)下面的協(xié)議方法

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *, id> *)advertisementData RSSI:(NSNumber *)RSSI {
     /*這邊可以打印設(shè)備的名稱,我們可以先將所有搜索到的設(shè)備都存儲起來顯示到UI上孤页,根據(jù)選擇來連接
      搜索到的設(shè)備會重復(fù)尔苦,所以需要過濾
      peripheral.name
     */
      if(![self.deviceLists containsObject: peripheral]){
          [self.deviceLists addObject: peripheral];
      }
}

6.連接外圍設(shè)備

選擇設(shè)備進(jìn)行連接
[central connectPeripheral:peripheral options:nil];

連接外圍設(shè)備,中心管理者連接外設(shè)成功行施,如果連接成功就會回調(diào)這個協(xié)議方法

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
    /連接成功之后允坚,可以進(jìn)行服務(wù)和特性的發(fā)現(xiàn)。 停止中心管理設(shè)備的掃描動作蛾号,要不然在你和已經(jīng)連接好的外設(shè)進(jìn)行數(shù)據(jù)溝通時(shí)稠项,如果又有一個外設(shè)進(jìn)行廣播且符合你的連接條件,那么你的iOS設(shè)備也會去連接這個設(shè)備(因?yàn)閕OS BLE4.0是支持一對多連接的)鲜结,導(dǎo)致數(shù)據(jù)的混亂展运。
    //停止掃描
    [self.centralManager stopScan];
    // 設(shè)置外設(shè)的代理
    peripheral.delegate = self;
    // 根據(jù)UUID來尋找服務(wù)
    //[peripheral discoverServices:@[[CBUUID UUIDWithString:SERVICE_UUID]]];
    //外設(shè)發(fā)現(xiàn)服務(wù),傳nil代表不過濾精刷,一次性讀出外設(shè)的所有服務(wù)
    [peripheral discoverServices:nil];
}

/** 連接失敗的回調(diào) */

- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
    NSLog(@"%s, line = %d, %@=連接失敗", __FUNCTION__, __LINE__, peripheral.name);
}

/** 斷開連接 */

- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error {
    NSLog(@"%s, line = %d, %@=斷開連接", __FUNCTION__, __LINE__, peripheral.name);
    // 斷開連接可以設(shè)置重新連接
    [central connectPeripheral:peripheral options:nil];
}

7拗胜、獲取外圍設(shè)備服務(wù)和特征
peripheral調(diào)用discoverServices方法之后,在下面的回調(diào)函數(shù)中發(fā)現(xiàn)服務(wù)

/** 發(fā)現(xiàn)服務(wù) */
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
    // 遍歷出外設(shè)中所有的服務(wù)
    for (CBService *service in peripheral.services) {
         //查找服務(wù)中所有的特征
         [peripheral discoverCharacteristics:nil forService:service];
    }
}

peripheral調(diào)用查詢對應(yīng)服務(wù)下面的特征之后贬养,會在下面的回調(diào)函數(shù)中返回

/** 發(fā)現(xiàn)特征 */
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
    if (error==nil) {
        for (CBCharacteristic *characteristic in service.characteristics){
            if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"49535343-8841-43F4-A8D4-ECBE34729BB3"]]){
                 self. characteristic = characteristic;
            }else if([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"49535343-1E4D-4BD9-BA61-23C647249616"]]){
                 [peripheral setNotifyValue:TRUE forCharacteristic:characteristic];
            }
            self.peripheral = peripheral;
        }
    }
}

到現(xiàn)在打印所需要的所有內(nèi)容都獲取到了挤土,就可以往打印機(jī)發(fā)送數(shù)據(jù)了

8、從外圍設(shè)備讀取數(shù)據(jù)
凡是從藍(lán)牙傳過來的數(shù)據(jù)都要經(jīng)過這個回調(diào)误算,簡單的說這個方法就是你拿數(shù)據(jù)的唯一方法仰美,你可以判斷是否 從外圍設(shè)備讀數(shù)據(jù)

/** 接收到數(shù)據(jù)回調(diào) */
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    NSData *data = characteristic.value; //獲取到的數(shù)據(jù)
    NSLog(@"bbb-----%@----",data); //打印出來應(yīng)該是<01a5>這樣的數(shù)據(jù)迷殿,可以通過下面的方式去判斷一些自己想要的邏輯
    Byte * resultByte = (Byte *)[data bytes];
    if(data.length>=1){
        if(resultByte[0]==16){ //16代表前兩位的值
            NSLog(@"---打印機(jī)打開---");
        }else if (resultByte[0]==1){ //01
            NSLog(@"----打印機(jī)缺紙-----");
        }
    }
    //下面的處理方式我沒處理過,大家可以試試
    //self.textFild.text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}

9咖杂、向藍(lán)牙設(shè)備寫數(shù)據(jù)

    Byte byte[] = {0x1B,0x68};//打印機(jī)狀態(tài)指令
    NSData *data = [[NSData alloc] initWithBytes:byte length:3];
    if(self.peripheral&&self.characteristic) {
        NSLog(@"發(fā)送獲取狀態(tài)指令");
        [peripheral writeValue:data forCharacteristic: characteristic type:CBCharacteristicWriteWithResponse];
    }

這里說明怎么連接上一次或者之前連接的設(shè)備庆寺,可以保存之前設(shè)備的標(biāo)識,進(jìn)入App之后通過這個標(biāo)識實(shí)例化服務(wù)來進(jìn)行鏈接诉字;通過這種方式不行的同學(xué)可以試試保存這個標(biāo)識懦尝,下次進(jìn)入的時(shí)候后臺掃描設(shè)備,判斷那個設(shè)備的標(biāo)識和存儲的一樣壤圃,連接表示一樣的那個...

//這個是需要保存的標(biāo)識
NSString *connectId = peripheral.identifier.UUIDString;
//進(jìn)入App之后獲取存儲的標(biāo)識進(jìn)行初始化服務(wù)
NSUUID *identifier = [[NSUUID UUID]initWithUUIDString: connectId];
CBPeripheral *peri = [[self.centralManager retrievePeripheralsWithIdentifiers:@[identifier]] firstObject];
if (peri == nil) {
    return;
}
if(peri.state==CBPeripheralStateConnected){
    [self alertMs:@"設(shè)備已被連接"];
    return;
}
[centralManager connectPeripheral:peri options:@{CBConnectPeripheralOptionNotifyOnConnectionKey : @YES}];

關(guān)于藍(lán)牙打印的知識暫時(shí)分享到這里陵霉,下面貼出參考的文章
藍(lán)牙的連接和數(shù)據(jù)的讀寫

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市伍绳,隨后出現(xiàn)的幾起案子踊挠,更是在濱河造成了極大的恐慌,老刑警劉巖冲杀,帶你破解...
    沈念sama閱讀 212,599評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件效床,死亡現(xiàn)場離奇詭異,居然都是意外死亡权谁,警方通過查閱死者的電腦和手機(jī)剩檀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來旺芽,“玉大人沪猴,你說我怎么就攤上這事〔烧拢” “怎么了字币?”我有些...
    開封第一講書人閱讀 158,084評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長共缕。 經(jīng)常有香客問我洗出,道長,這世上最難降的妖魔是什么图谷? 我笑而不...
    開封第一講書人閱讀 56,708評論 1 284
  • 正文 為了忘掉前任翩活,我火速辦了婚禮,結(jié)果婚禮上便贵,老公的妹妹穿的比我還像新娘菠镇。我一直安慰自己,他們只是感情好承璃,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,813評論 6 386
  • 文/花漫 我一把揭開白布利耍。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪隘梨。 梳的紋絲不亂的頭發(fā)上程癌,一...
    開封第一講書人閱讀 50,021評論 1 291
  • 那天,我揣著相機(jī)與錄音轴猎,去河邊找鬼嵌莉。 笑死,一個胖子當(dāng)著我的面吹牛捻脖,可吹牛的內(nèi)容都是我干的锐峭。 我是一名探鬼主播,決...
    沈念sama閱讀 39,120評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼可婶,長吁一口氣:“原來是場噩夢啊……” “哼沿癞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起矛渴,我...
    開封第一講書人閱讀 37,866評論 0 268
  • 序言:老撾萬榮一對情侶失蹤抛寝,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后曙旭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,308評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡晶府,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,633評論 2 327
  • 正文 我和宋清朗相戀三年桂躏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片川陆。...
    茶點(diǎn)故事閱讀 38,768評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡剂习,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出较沪,到底是詐尸還是另有隱情鳞绕,我是刑警寧澤,帶...
    沈念sama閱讀 34,461評論 4 333
  • 正文 年R本政府宣布尸曼,位于F島的核電站们何,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏控轿。R本人自食惡果不足惜冤竹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,094評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望茬射。 院中可真熱鬧鹦蠕,春花似錦、人聲如沸在抛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至肠阱,卻和暖如春票唆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背辖所。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評論 1 267
  • 我被黑心中介騙來泰國打工惰说, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人缘回。 一個月前我還...
    沈念sama閱讀 46,571評論 2 362
  • 正文 我出身青樓吆视,卻偏偏與公主長得像,于是被迫代替她去往敵國和親酥宴。 傳聞我的和親對象是個殘疾皇子啦吧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,666評論 2 350

推薦閱讀更多精彩內(nèi)容