在上一篇中介绍了打印小票所需要的命令,这一篇介绍 Bluetooth 连接蓝牙和打印小票的全过程。
因为 CoreBluetooth 中的代理太多,而每一次操作又比较依赖上一次操作的结果,方法又比较零散,所以我做了粗略封装,把代理改成了 block 方式回调。
- HLBLEManager *manager = [HLBLEManager sharedInstance];
- __weakHLBLEManager *weakManager = manager;
- manager.stateUpdateBlock= ^(CBCentralManager *central) {NSString*info =nil;switch(central.state) {caseCBCentralManagerStatePoweredOn:
- info = @"蓝牙已打开,并且可用";//三种种方式
- // 方式1[weakManager scanForPeripheralsWithServiceUUIDs:niloptions:nil];// 方式2[central scanForPeripheralsWithServices:niloptions:nil];// 方式3[weakManager scanForPeripheralsWithServiceUUIDs:niloptions:nildidDiscoverPeripheral:^(CBCentralManager *central, CBPeripheral *peripheral,NSDictionary*advertisementData,NSNumber*RSSI) {
- }];break;caseCBCentralManagerStatePoweredOff:
- info = @"蓝牙可用,未打开";break;caseCBCentralManagerStateUnsupported:
- info = @"SDK不支持";break;caseCBCentralManagerStateUnauthorized:
- info = @"程序未授权";break;caseCBCentralManagerStateResetting:
- info = @"CBCentralManagerStateResetting";break;caseCBCentralManagerStateUnknown:
- info = @"CBCentralManagerStateUnknown";break;
- }
- [SVProgressHUD setDefaultStyle:SVProgressHUDStyleDark];
- [SVProgressHUD showInfoWithStatus:info ];
- };
因为 CBCentralManager 一创建,就会在代理中返回蓝牙模块的状态,所以及时设置状态返回的回调,以便在搜索附近可用的蓝牙外设。
- // 方式1[weakManager scanForPeripheralsWithServiceUUIDs:niloptions:nil];// 方式2[central scanForPeripheralsWithServices:niloptions:nil];// 方式3[weakManager scanForPeripheralsWithServiceUUIDs:niloptions:nildidDiscoverPeripheral:^(CBCentralManager *central, CBPeripheral *peripheral,NSDictionary*advertisementData,NSNumber*RSSI) {
- }];
这里给出了三种方式,前两种方式都需要先设置好搜索到蓝牙外设之后的回调, 即:
- manager.discoverPeripheralBlcok = ^(CBCentralManager * central, CBPeripheral * peripheral, NSDictionary * advertisementData, NSNumber * RSSI) {
- if (peripheral.name.length <= 0) {
- return;
- }
- if (self.deviceArray.count == 0) {
- NSDictionary * dict = @ {@"peripheral": peripheral,
- @"RSSI": RSSI
- }; [self.deviceArray addObject: dict];
- } else {
- BOOL isExist = NO;
- for (int i = 0; i < self.deviceArray.count; i++) {
- NSDictionary * dict = [self.deviceArray objectAtIndex: i];
- CBPeripheral * per = dict[@"peripheral"];
- if ([per.identifier.UUIDString isEqualToString: peripheral.identifier.UUIDString]) {
- isExist = YES;
- NSDictionary * dict = @ {@"peripheral": peripheral,
- @"RSSI": RSSI
- }; [_deviceArray replaceObjectAtIndex: i withObject: dict];
- }
- }
- if (!isExist) {
- NSDictionary * dict = @ {@"peripheral": peripheral,
- @"RSSI": RSSI
- }; [self.deviceArray addObject: dict];
- }
- } [self.tableView reloadData];
- };
- }
第三种方式,则附带一个 block,便于直接处理。
- HLBLEManager *manager = [HLBLEManager sharedInstance];
- [manager connectPeripheral:_perpheral
- connectOptions:@{CBConnectPeripheralOptionNotifyOnDisconnectionKey:@(YES)}
- stopScanAfterConnected:YESservicesOptions:nilcharacteristicsOptions:nilcompleteBlock:^(HLOptionStage stage, CBPeripheral *peripheral, CBService *service, CBCharacteristic *character,NSError*error) {switch(stage) {caseHLOptionStageConnection:
- {if(error) {
- [SVProgressHUD showErrorWithStatus:@"连接失败"];
- }else{
- [SVProgressHUD showSuccessWithStatus:@"连接成功"];
- }break;
- }caseHLOptionStageSeekServices:
- {if(error) {
- [SVProgressHUD showSuccessWithStatus:@"查找服务失败"];
- }else{
- [SVProgressHUD showSuccessWithStatus:@"查找服务成功"];
- [_infos addObjectsFromArray:peripheral.services];
- [_tableView reloadData];
- }break;
- }caseHLOptionStageSeekCharacteristics:
- {// 该block会返回多次,每一个服务返回一次
- if(error) {NSLog(@"查找特性失败");
- }else{NSLog(@"查找特性成功");
- [_tableView reloadData];
- }break;
- }caseHLOptionStageSeekdescriptors:
- {// 该block会返回多次,每一个特性返回一次
- if(error) {NSLog(@"查找特性的描述失败");
- }else{NSLog(@"查找特性的描述成功");
- }break;
- }default:break;
- }
- }];
这些操作都是有阶段性的,并且依赖上一步的结果。 这里我也给出了两种方式:
- /** 连接外设完成的回调 */
- @property(copy, nonatomic) HLConnectCompletionBlock connectCompleteBlock;/** 发现服务的回调 */
- @property(copy, nonatomic) HLDiscoveredServicesBlock discoverServicesBlock;/** 发现服务中的特性的回调 */
- @property(copy, nonatomic) HLDiscoverCharacteristicsBlock discoverCharacteristicsBlock;/** 发现特性的描述的回调 */
- @property(copy, nonatomic) HLDiscoverDescriptorsBlock discoverDescriptorsBlock;
- CBCharacteristic *character =[service.characteristics objectAtIndex:indexPath.row];
- CBCharacteristicPropertiesproperties=character.properties;if(properties& CBCharacteristicPropertyWriteWithoutResponse){
- self.chatacter = character;
- }
- NSString*title = @"测试电商";NSString*str1 = @"测试电商服务中心(销售单)";
- HLPrinter *printer = [[HLPrinter alloc] init];
- [printer appendText:title alignment:HLTextAlignmentCenter fontSize:HLFontSizeTitleBig];
- [printer appendText:str1 alignment:HLTextAlignmentCenter];
- [printer appendBarCodeWithInfo:@"RN3456789012"];
- [printer appendSeperatorLine];
- [printer appendTitle:@"时间:"value:@"2016-04-27 10:01:50"valueOffset:150];
- [printer appendTitle:@"订单:"value:@"4000020160427100150"valueOffset:150];
- [printer appendText:@"地址:深圳市南山区学府路东深大店"alignment:HLTextAlignmentLeft];
- [printer appendSeperatorLine];
- [printer appendLeftText:@"商品"middleText:@"数量"rightText:@"单价"isTitle:YES];CGFloattotal =0.0;for(NSDictionary*dict in goodsArray) {
- [printer appendLeftText:dict[@"name"] middleText:dict[@"amount"] rightText:dict[@"price"] isTitle:NO];
- total += [dict[@"price"] floatValue] * [dict[@"amount"] intValue];
- }
- [printer appendSeperatorLine];NSString*totalStr = [NSStringstringWithFormat:@"%.2f",total];
- [printer appendTitle:@"总计:"value:totalStr];
- [printer appendTitle:@"实收:"value:@"100.00"];NSString*leftStr = [NSStringstringWithFormat:@"%.2f",100.00- total];
- [printer appendTitle:@"找零:"value:leftStr];
- [printer appendFooter:nil];
- [printer appendImage:[UIImageimageNamed:@"ico180"] alignment:HLTextAlignmentCenter maxWidth:300];
- NSData *mainData = [printer getFinalData];
- HLBLEManager *bleManager = [HLBLEManager sharedInstance];
- [bleManager writeValue:mainDataforCharacteristic:self.chatactertype:CBCharacteristicWriteWithoutResponse];
写入数据后,蓝牙打印机就会开始打印小票。
- HLPrinter * printer = [[HLPrinter alloc] init];在创建这个打印机操作对象时,内部做了很多预设置: - (instancetype) init {
- self = [super init];
- if (self) { [self defaultSetting];
- }
- return self;
- } - (void) defaultSetting {
- _printerData = [[NSMutableData alloc] init];
- // 1.初始化打印机
- Byte initBytes[] = {
- 0x1B,
- 0x40
- }; [_printerData appendBytes: initBytes length: sizeof(initBytes)];
- // 2.设置行间距为1/6英寸,约34个点
- // 另一种设置行间距的方法看这个 @link{-setLineSpace:}
- Byte lineSpace[] = {
- 0x1B,
- 0x32
- }; [_printerData appendBytes: lineSpace length: sizeof(lineSpace)];
- // 3.设置字体:标准0x00,压缩0x01;
- Byte fontBytes[] = {
- 0x1B,
- 0x4D,
- 0x00
- }; [_printerData appendBytes: fontBytes length: sizeof(fontBytes)];
- }
可以打印的内容包括:文字、二维码、条形码、图片。 而对这些内容的处理已经做了封装,只需要简单调用某些 API 即可。
- /**
- * 添加单行标题,默认字号是小号字体
- *
- * @paramtitle 标题名称
- * @paramalignment 标题对齐方式
- */- (void)appendText:(NSString *)text alignment:(HLTextAlignment)alignment;/**
- * 添加单行标题
- *
- * @paramtitle 标题名称
- * @paramalignment 标题对齐方式
- * @paramfontSize 标题字号
- */- (void)appendText:(NSString *)text alignment:(HLTextAlignment)alignment fontSize:(HLFontSize)fontSize;
- /**
- * 添加单行信息,左边名称(左对齐),右边实际值(右对齐)。
- * @paramtitle 名称
- * @paramvalue 实际值
- * @paramfontSize 字号大小
- * 警告:因字号和字体与iOS中字体不一致,计算出来有误差
- */- (void)appendTitle:(NSString *)title value:(NSString *)value fontSize:(HLFontSize)fontSize;/**
- * 设置单行信息,左标题,右实际值
- *
- * @paramtitle 标题
- * @paramvalue 实际值
- * @paramoffset 实际值偏移量
- */- (void)appendTitle:(NSString *)title value:(NSString *)value valueOffset:(NSInteger)offset;/**
- * 设置单行信息,左标题,右实际值
- *
- * @paramtitle 标题
- * @paramvalue 实际值
- * @paramoffset 实际值偏移量
- * @paramfontSize 字号
- */- (void)appendTitle:(NSString *)title value:(NSString *)value valueOffset:(NSInteger)offset fontSize:(HLFontSize)fontSize;
- /**
- * 添加选购商品信息标题,一般是三列,名称、数量、单价
- *
- * @paramLeftText 左标题
- * @parammiddleText 中间标题
- * @paramrightText 右标题
- */- (void)appendLeftText:(NSString *)left middleText:(NSString *)middle rightText:(NSString *)right isTitle:(BOOL)isTitle;
- /**
- * 添加条形码图片
- *
- * @paraminfo 条形码中包含的信息,默认居中显示,最大宽度为300。如果大于300,会等比缩放。
- */- (void)appendBarCodeWithInfo:(NSString *)info;/**
- * 添加条形码图片
- *
- * @paraminfo 条形码中的信息
- * @paramalignment 图片对齐方式
- * @parammaxWidth 图片最大宽度
- */- (void)appendBarCodeWithInfo:(NSString *)info alignment:(HLTextAlignment)alignment maxWidth:(CGFloat)maxWidth;
- /**
- * 添加二维码图片
- *
- * @paraminfo 二维码中的信息
- */- (void)appendQRCodeWithInfo:(NSString *)info;/**
- * 添加二维码图片
- *
- * @paraminfo 二维码中的信息
- * @paramcenterImage 二维码中间的图片
- * @paramalignment 对齐方式
- * @parammaxWidth 二维码的最大宽度
- */- (void)appendQRCodeWithInfo:(NSString *)info centerImage:(UIImage *)centerImage alignment:(HLTextAlignment)alignment maxWidth:(CGFloat )maxWidth;
- /**
- * 添加图片,一般是添加二维码或者条形码
- *
- * @paramimage 图片
- * @paramalignment 图片对齐方式
- * @parammaxWidth 图片的最大宽度,如果图片过大,会等比缩放
- */- (void)appendImage:(UIImage *)image alignment:(HLTextAlignment)alignment maxWidth:(CGFloat)maxWidth;
- /**
- * 添加一条分割线,like this:---------------------------
- */- (void)appendSeperatorLine;
- /**
- * 添加底部信息
- *
- * @paramfooterInfo 不填默认为 谢谢惠顾,欢迎下次光临!
- */- (void)appendFooter:(NSString *)footerInfo;
- /**
- * 获取最终的data
- *
- * @return最终的data
- */- (NSData *)getFinalData;
HLPrinter 内部实际有一些私有方法,都是对上一篇内容中打印机命令的封装,作为基础操作
- /**
- * 换行
- */
- - (void) appendNewLine {
- Byte nextRowBytes[] = {
- 0x0A
- }; [_printerData appendBytes: nextRowBytes length: sizeof(nextRowBytes)];
- }
- /**
- * 回车
- */
- - (void) appendReturn {
- Byte returnBytes[] = {
- 0x0D
- }; [_printerData appendBytes: returnBytes length: sizeof(returnBytes)];
- }
- /**
- * 设置对齐方式
- *
- * @param alignment 对齐方式:居左、居中、居右
- */
- - (void) setAlignment: (HLTextAlignment) alignment {
- Byte alignBytes[] = {
- 0x1B,
- 0x61,
- alignment
- }; [_printerData appendBytes: alignBytes length: sizeof(alignBytes)];
- }
- /**
- * 设置字体大小
- *
- * @param fontSize 字号
- */
- - (void) setFontSize: (HLFontSize) fontSize {
- Byte fontSizeBytes[] = {
- 0x1D,
- 0x21,
- fontSize
- }; [_printerData appendBytes: fontSizeBytes length: sizeof(fontSizeBytes)];
- }
在
中,主要是对图片操作的两个 Category, 一个是创建二维码、条形码图片。 另一是将图片转换为点阵图数据。
- UIImage+Bitmap
可能对于小票的样式不仅仅局限于封装的几种,有人提到左边二维码图片,右边居中显示一些文字的布局方式,这样用原来的指令集组合的方式就很难实现。 对于一些不太好弄的布局样式,我们可以曲线救国,这里有一些新的场景和解决方案:
iOS CoreBluetooth 的使用讲解
原文作者其他链接推荐:iOS Bluetooth 打印小票(一)
来源: http://blog.csdn.net/ws1352864983/article/details/70255681