iOS如何完成蓝牙打印机功能

写在前面:因为哥们 @骑驴追蝴蝶 遇到了打印图片的功能,这个demo 是支持打印图片的,打印图片代码我单独放在文章最后,有需要的哥们可以去试试

之前公司项目里面需要使用到蓝牙打印机这个功能,搞定后特来向兄弟们分享一下经验和坑。

废话不多说,直接上代码

1.需要导入一些库,这些库是当时看的demo上面需要的,因为时间紧,我没有试过是不是每个库都是需要的,还望兄弟们见谅,不过全部加上是没有错的。

注意:payUpDate不需要添加


ACAFF20F-7556-4335-94E0-D1B8EFA8AC97.png
2.导入PrinterSDK,这个SDK我会随demo一起放出。

9C7F1FA1-5E5C-4CCC-AF21-8EF8C35CB9B0.png
3.先检测是否能够自动连接,因为蓝牙打印机直有第一次连接是费时间的,其他时候只需要调用自动连接即可
AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    //自动连接上一次使用的打印机
    [PrinterWraper autoConnectLastPrinterTimeout:6.0 Completion:^(NSString *uid) {

        NSLog(@"自动连接 uid=%@",uid);

        if (uid) {

            //连接成功后发送通知
            [[NSNotificationCenter defaultCenter] postNotificationName:KConnectionSuccess object:nil];

        }else{

            [SVProgressHUD dismiss];
        }
    }];

    return YES;
}
4.创建一个专门用来管理打印机的类
.h里面基本上面没有什么

#import <Foundation/Foundation.h>

@interface iOS : NSObject

//直接调用该方法,启动打印机(jsonstring是后台传过来的数据)
- (void)print:(NSString *)jsonString;

@end
.m

#import "iOS.h"

#import <CoreBluetooth/CoreBluetooth.h>

@interface iOS()<BluetoothDelegate,UIAlertViewDelegate>

@property (nonatomic, strong) NSTimer *mytimer;


@property (nonatomic, strong)  NSArray*deviceList;


@property (nonatomic, copy) NSString *jsonString;


@property (nonatomic, assign) BOOL isAutoConnectionSuccess;

// 通知监听对象
@property (nonatomic, strong) id observer;

@end

@implementation iOS


- (instancetype)init{

    if (self = [super init]) {

        self.isAutoConnectionSuccess = NO;

        __weak iOS * weakSelf = self;

        //自动连接后,会到这里来,通知的接收
        self.observer = [[NSNotificationCenter defaultCenter] addObserverForName:KConnectionSuccess object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {

            weakSelf.isAutoConnectionSuccess = YES;

        }];

    }

    return self;
}

#pragma mark bluetooth delegate 检测蓝牙是否打开,这里是会自动调用的
-(void)BlueToothOpen:(BOOL)isopen;{

    if (!isopen) {

        //因为我这里是在webview里面进行的,可能有线程问题,所以我将弹框操作,全部放在主线程里面完成的
        dispatch_async(dispatch_get_main_queue(), ^{

            [SVProgressHUD showSuccessWithStatus:@"请打开蓝牙设备"];
        });

    }
}

//这里会去寻找打印机是否存在
- (void)scanPrinter{

    [PrinterWraper SetBlutoothDelegate:self];
    [PrinterWraper StartScanTimeout:5];

    dispatch_async(dispatch_get_main_queue(), ^{

        [SVProgressHUD showWithStatus:@"连接蓝牙打印机中..."];
    });


    self.mytimer = [NSTimer scheduledTimerWithTimeInterval:6.0 target:self selector:@selector(timeout) userInfo:nil repeats:NO];

}

-(void)stopScan{

    [PrinterWraper StopScan];

    [self.mytimer invalidate];

    self.mytimer=nil;
}

#pragma mark  查找设备时间到,会调用这个方法,devicelist里面不需要赋值,就会有值,这也是我使用这个框架最大的坑
-(void)timeout{

    [self stopScan];

    BOOL isSuccess = NO;

    for (int i = 0; i < self.deviceList.count; i++) {

        if (self.deviceList[i]) {

            CBPeripheral *device = self.deviceList[i];

            //这里是你们蓝牙打印机的名字,你需要看看你们的蓝牙打印机设定的是什么名字
            if ([device.name isEqualToString:@"Bluetooth Printer"]) {
                //连接打印机
                [PrinterWraper connectPrinter:device.identifier.UUIDString shouldreset:NO];

                [SVProgressHUD dismiss];

                isSuccess = YES;

            }
        }
    }

    if (!isSuccess)
    {
        dispatch_async(dispatch_get_main_queue(), ^{

            [SVProgressHUD dismiss];

            UIAlertView* alert=[[UIAlertView alloc] initWithTitle:nil message:NSLocalizedString(@"没有扫描到专用打印机",@"") delegate:nil cancelButtonTitle:NSLocalizedString(@"确定", @"") otherButtonTitles:nil, nil];

            [alert show];
        });

    }
}

#pragma mark 注销通知
- (void)dealloc{

    [[NSNotificationCenter defaultCenter] removeObserver:self.observer];

}

#pragma mark -打印jsonString
- (void)print:(NSString *)jsonString{

    self.jsonString = jsonString;

    if (self.isAutoConnectionSuccess) {

        [self printJsonWithBluetoothPrinter:self.jsonString];

        return;
    }

    [self scanPrinter];

}

#pragma mark 连接上会自动调用这个方法
-(void)didConnected:(NSString*)deviceUid  Result:(BOOL)success;{

    if (success){

        [self printJsonWithBluetoothPrinter:self.jsonString];

    }  
}


//这里是设置你打印的内容,我这里保留下来兄弟们参考
- (void)printJsonWithBluetoothPrinter:(NSString *)jsonString{

#warning 请确保本身的navigationController是有效的
#warning 工程的General->Embedded Binaries  + PrinterSdk.framework
#warning 请试用真机 否则会有编译错误

    //jsonstring 是后台传过来的,这里考虑到兄弟们也应该是从网络上面请求来的数据,估计也需要同样处理,所以没有注释掉

    NSData * data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];

    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];

    //设置格式 大字体 行间距28 局中
    [PrinterWraper setPrintFormat:3 LineSpace:28 alinment:1 rotation:0];// 3 大字体  ,28默认行间距,1局中对齐

    [PrinterWraper addPrintText:[NSString stringWithFormat:@"%@%@",[self checkString:dic[@"brand_name"]],[self checkString:dic[@"origin"]]]];

    [PrinterWraper setPrintFormat:1 LineSpace:28 alinment:0 rotation:0];

    [PrinterWraper addPrintText:@"*"];

    [PrinterWraper setPrintFormat:3 LineSpace:28 alinment:1 rotation:0];// 3 大字体  ,28默认行间距,1局中对齐

    //打印标题
    [PrinterWraper addPrintText:[NSString stringWithFormat:@"%@\n",[self checkString:dic[@"serial"]]]];



    //设置标题的格式
    [PrinterWraper setPrintFormat:1 LineSpace:28 alinment:0 rotation:0];// 1 小字体  ,28默认行间距,0左对齐

    //打印副标题
    [PrinterWraper addPrintText:@"哈哈哈哈  客服电话: 4000-000-000\n"];//打印文字

    //设置副标题的格式
    [PrinterWraper setPrintFormat:1 LineSpace:28 alinment:0 rotation:0];// 1 小字体  ,28默认行间距,0左对齐

    //打印副标题
    [PrinterWraper addPrintText:@"********************************\n"];//打印文字

    NSArray *headers =@[@"菜单",@"单价",@"数量"];


    NSArray * goodArr = dic[@"lines"];

    NSMutableArray * mutableArr = [NSMutableArray arrayWithCapacity:goodArr.count];


    for (NSInteger i = 0; i<goodArr.count; i++) {

        NSMutableArray * arr  = [NSMutableArray array];

        [arr addObject:[self checkString:dic[@"lines"][i][@"product_name"]]];
        [arr addObject:[dic[@"lines"][i][@"unit_price_incl_tax"] stringValue]];
        [arr addObject:[NSString stringWithFormat:@"X%@",[self checkString:dic[@"lines"][i][@"quantity"]]]];

        [mutableArr addObject:arr];
    }

    NSMutableArray * body = [NSMutableArray array];

    [body addObject:headers];

    for (NSInteger i = 0; i < mutableArr.count; i++) {

        [body addObject:mutableArr[i]];

    }

    //打印商品列表,会自动排版,要求数组长度一致,空白地方用@""
    [PrinterWraper addItemLines:body];


    //设置格式 大字体 行间距28 局中
    [PrinterWraper setPrintFormat:3 LineSpace:28 alinment:1 rotation:0];// 3 大字体  ,28默认行间距,1局中对齐

    NSString * product_total_price = @"";

    if (!dic[@"product_total_price"]) {

        product_total_price = @"0";

    }else{

        product_total_price = [dic[@"product_total_price"] stringValue];
    }


    NSString *str = [NSString stringWithFormat:@"\n合计: %@(元)\n",product_total_price];


    [PrinterWraper addPrintText:str];//打印文字

    //设置副标题的格式
    [PrinterWraper setPrintFormat:1 LineSpace:28 alinment:0 rotation:0];// 1 小字体  ,28默认行间距,0左对齐

    //打印副标题
    [PrinterWraper addPrintText:@"********************************\n"];//打印文字

    NSArray *values0_1 =@[@"订单类型:",[self checkString:dic[@"order_type"]]];
    NSArray *values1_1 =@[@"订单渠道:",[self checkString:dic[@"origin"]]];
    NSArray *values2_1 =@[@"服务品牌:",[self checkString:dic[@"brand_name"]]];
    NSArray *values3_1 =@[@"服务门店:",[self checkString:dic[@"partner_name"]]];
    NSArray *values4_1 =@[@"门店电话:",[self checkString:dic[@"service_phone"]]];
    NSArray *values5_1 =@[@"下单时间:",[self checkString:dic[@"date_placed"]]];
    NSArray *values6_1 =@[@"送餐时间:", [NSString stringWithFormat:@"%@ 【%@】",[self checkString:dic[@"shipping_method"]],[self checkString:dic[@"delivery_time"]]]];
    NSArray *values7_1 =@[@"支付方式:",[self checkString:dic[@"payment_method"]]];
    NSArray* body_1 =@[values0_1,values1_1,values2_1,values3_1,values4_1,values5_1,values6_1,values7_1];


    //打印商品列表,会自动排版,要求数组长度一致,空白地方用@""
    [PrinterWraper addItemLines:body_1];

    //设置副标题的格式
    [PrinterWraper setPrintFormat:1 LineSpace:28 alinment:0 rotation:0];// 1 小字体  ,28默认行间距,0左对齐

    //打印副标题
    [PrinterWraper addPrintText:@"********************************\n"];//打印文字

    [PrinterWraper addPrintText:[self checkString:dic[@"customer_name"]]];

    NSString * genderStr;

    if ([[self checkString:dic[@"customer_gender"]] isEqualToString:@"男"]) {

        genderStr = @"  先生\n";

    }else if([[self checkString:dic[@"customer_gender"]] isEqualToString:@"女"]){

        genderStr = @"  女士\n";

    }else{

        genderStr = @"  \n";

    }

    [PrinterWraper addPrintText:genderStr];

    [PrinterWraper addPrintText: [NSString stringWithFormat:@"%@\n",[self checkString:dic[@"customer_phone"]]]];

    [PrinterWraper addPrintText: [NSString stringWithFormat:@"%@\n",[self checkString:dic[@"delivery_address"]]]];

    //打印副标题
    [PrinterWraper addPrintText:@"********************************\n"];//打印文字

    //打印副标题
    [PrinterWraper addPrintText:@"骑士签名:"];

    [PrinterWraper addPrintText:@"\n\n\n\n\n\n"];//打印文字
    //    开始启动打印
    //    [PrinterWraper startPrint:self.navigationController];

    BOOL res=   [PrinterWraper startPrint:nil];

}

- (NSString *)checkString:(id)str{

    if (str) {

        return (NSString *)str;

    }else{

        return @"";
    }
}
@end
5.对上面的代码做一些解释
  1. 首先在appdelegate里面进行自动连接上一次使用过的打印机

2.如果能够自动连接,会更改管理类里面的isAutoConnectionSuccess 的值

3.直接调用管理类的,这个方法会根据isAutoConnectionSuccess判断是否自动连接上了

- (void)print:(NSString *)jsonString

4.自动连接上了直接跳鞋打印内容,然后进行打印即可

5.没有自动连接就需要调用下面方法来完成打印机的搜索

[self scanPrinter];

6.搜索的时候deviceList里面会自动进行赋值(这也是这个框架最坑的地方,不调试,根本无法进行)

7.根据deviceList里面设备进行判断,哪个是蓝牙打印机

    for (int i = 0; i < self.deviceList.count; i++) {

        if (self.deviceList[i]) {

            CBPeripheral *device = self.deviceList[i];

            if ([device.name isEqualToString:@"Bluetooth Printer"]) {
                //连接打印机
                [PrinterWraper connectPrinter:device.identifier.UUIDString shouldreset:NO];

                [SVProgressHUD dismiss];

                isSuccess = YES;

            }
        }
    }

8.连接上了打印机后,会调用这个方法

-(void)didConnected:(NSString*)deviceUid  Result:(BOOL)success;{

    if (success){

        [self printJsonWithBluetoothPrinter:self.jsonString];

    }

}

9.然后填写打印内容即可,至于格式,我想兄弟们看看我的代码基本上也知道什么回事了

6.打印效果

O8{N~FYBFNAD~NG8YKZ`0~T.jpg

注:下面的代码时打印图片的,

- (void)print:(NSString *)jsonString{

[PrinterWraper addPrintImage:[UIImage imageWithContentsOfFile:photopath]];
   //打印标题
     [PrinterWraper addPrintText:@"掌上科技有限公司"];//打印文字
//    设置主体内容 小字体
    [PrinterWraper setPrintFormat:1 LineSpace:28 alinment:0 rotation:0];// 1 小字体  ,28默认行间距,0左对齐

    [PrinterWraper addPrintText:@"掌上开单打印机高质量稳定速度快\n联系QQ40255986 手机15988879319\n"];//打印文字


//打印商品列表,会自动排版,要求数组长度一致,空白地方用@""
    [PrinterWraper addItemLines:body];
//打印二维码
    [PrinterWraper addPrintBarcode:@"http://www.baidu.com" isTwoDimensionalCode:1];//二维码
//    打印一维码 必须是12-13位数字
    [PrinterWraper addPrintBarcode:@"123456789012" isTwoDimensionalCode:0];//1维码
    [PrinterWraper addPrintBarcode:@"123456789013" isTwoDimensionalCode:0];//1维码


    [PrinterWraper addPrintText:@"\n\n"];//打印文字
//    开始启动打印
//    [PrinterWraper startPrint:self.navigationController];

}

附上demo地址,demo是直接拿的第三方提供的,但是里面有很多东西可能用不上,兄弟们按照我上面写的基本就ok了,因为我的代码是公司的,所以不敢使用,还望见谅!

https://github.com/knightSaber/PrinterDemoDev

https://github.com/newOcean/printer



文/小小流浪的汉子(简书作者)
原文链接:http://www.jianshu.com/p/4fa9eb1def6e
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值