前言:AirPrint技术存在已经有了很长的时间,但是对于通常实现来说,每次打印都需要用户在客户端点击选择打印机并确认打印,流程上很不方便。所幸的是apple在iOS8更新了此技术,使其可以支持iOS设备上的无交互后台打印。本文介绍了无交互打印的流程、原理和相关实现,并贴出源代码。

关于AirPrint

AirPrint 是可以让应用软件通过 Apple 的无驱动程序打印体系结构,创建无损打印输出的 Apple 技术。所有支持打印的 iOS 内建 app 均使用 AirPrint。App Store 上使用 iOS 打印系统的 App 也使用 AirPrint。官方 AirPrint 打印机和服务器经过 Apple 许可和认证。(以上文字来自百度百科)
简单说来,airPrint就是苹果定义的一种相对通用的规范或者说标准,满足这种规范的打印机就可以直接连接iOS设备进行打印(无需安装驱动)。而对于客户端来说,只需要调用苹果airPrint的相关API就可以实现连接airPrint打印机的打印,而无需集成各个厂商的sdk,大大方便的编程实现。

AirPrint打印简单实现(iOS8以前的解决方案)

主要代码如下:

- (IBAction)airPrint:(id)sender {UIPrintInteractionController *controller = [UIPrintInteractionController sharedPrintController];if(!controller){NSLog(@"Couldn't get shared UIPrintInteractionController!");return;}/* Set this object as delegate so you can  use the printInteractionController:cutLengthForPaper: delegate */controller.delegate = self;/************************* Set Print Info ************************/UIPrintInfo *printInfo = [UIPrintInfo printInfo];/* Four types of UIPrintInfoOutputType you can assign to, and Paper Size Selection will be shown in the AirPrint View,those Paper Sizes to be shown also depends on what kind of OutputType you selected , and the locale of your iDevice */printInfo.outputType = UIPrintInfoOutputPhoto;/* Use landscape orientation for a banner so the text  print along the long side of the paper. */printInfo.orientation = UIPrintInfoOrientationPortrait; // UIPrintInfoOrientationPortrait or UIPrintInfoOrientationLandscapeprintInfo.jobName = @"AirPrintWechatSize";controller.printInfo = printInfo;/******* Set Image to Print ***/UIImage *printImage = [UIImage imageNamed:@"7.jpg"];controller.printingItem = printImage;/************************* Print ************************//* Set up a completion handler block.  If the print job has an error before spooling, this is where it's handled. */void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) = ^(UIPrintInteractionController *printController, BOOL completed, NSError *error) {if(completed && error)NSLog( @"Printing failed due to error in domain %@ with error code %lu. Localized description: %@, and failure reason: %@", error.domain, (long)error.code, error.localizedDescription, error.localizedFailureReason );};if([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {//iPad[controller presentFromRect:self.view.frame inView:self.view animated:YES completionHandler:completionHandler];}else{[controller presentAnimated:YES completionHandler:completionHandler];}}

iOS8以前实现的步骤和缺陷

这里主要步骤如下:
1.获取UIPrintInteractionController
2.设置Print Info
3.设置printingItem
4.设置打印回调
5.弹出UIPrintInteractionController
这里的缺陷在于我们每次打印都需要弹出这个UIPrintInteractionController,在其中进行打印机的选择并确认打印。但是很多情况下,我们希望这个过程能够在后台执行,我们的程序可以更智能,交互体验更棒。

Print without UI

首先是选择并保存打印机信息的代码:

  UIPrinterPickerController *pickerController =[UIPrinterPickerController printerPickerControllerWithInitiallySelectedPrinter:nil];CGRect rect;UIInterfaceOrientation currentOrientation = [UIApplication sharedApplication].statusBarOrientation;rect = CGRectMake(320, 130, 0, 0);[pickerController presentFromRect:rect inView:self.view animated:YES completionHandler:^(UIPrinterPickerController *controller, BOOL userDidSelect, NSError *err){if (userDidSelect){// save the urlString and Printer name, do your UI interactionsself.printerName.text = controller.selectedPrinter.displayName;self.submitButton.enabled = YES;GSignInConfig.airPrinterUrlStr = controller.selectedPrinter.URL.absoluteString;GSignInConfig.airPrinterName = controller.selectedPrinter.displayName;DDLogInfo(@"Selected printer:%@", controller.selectedPrinter.displayName);}}];

UIPrinterPickerController需要iOS 8+;其设计理念是通过一次用户交互将打印机相关信息从iOS系统传递到客户端,客户端后续可以用这些信息来进行打印。这里最关键的信息是controller.selectedPrinter.URL.absoluteString,有了它我们就可以找到打印机了(前提是打印机和iOS设备的网络连接情况没有变化)。GSignInConfig是我自己实现的配置持久化接口,可以简单理解成userdefault,这里持久化了打印机的absoluteString和displayName。

[
[UIPrinter printerWithURL:[NSURL URLWithString:printerUrlStr]] contactPrinter:^(BOOL available){if (available){DDLogInfo(@"AIRPRINTER AVAILABLE");}else{DDLogInfo(@"AIRPRINTER NOT AVAILABLE");}}];

上面的代码实现了打印机连接状态的后台检查;这里的printerUrlStr就是此前获取并保存的absoluteUrl。通过它我们就可以构建出一个UIPrinter对象了。这个步骤需要在实际打印操作前完成。

- (void)startAirPrintWithImage:(UIImage *)image
{/************************* Set Print Info ************************/UIPrintInfo *printInfo = [UIPrintInfo printInfo];printInfo.outputType = UIPrintInfoOutputGeneral;printInfo.orientation = UIPrintInfoOrientationPortrait;printInfo.jobName = @"CoolVisitAirPrint";self.airPrinterController.printInfo = printInfo;self.airPrinterController.printingItem = image;self.airPrinterController.delegate = self;/************************* Print ************************//* Set up a completion handler block.  If the print job has an error before spooling, this is where it's handled. */void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) = ^(UIPrintInteractionController *printController, BOOL completed, NSError *error) {if(completed && error)DDLogError(@"Printing failed due to error in domain %@ with error code %lu. Localized description: %@, and failure reason: %@", error.domain, (long)error.code, error.localizedDescription, error.localizedFailureReason);};UIPrinter *airPrinter = [UIPrinter printerWithURL:[NSURL URLWithString:GSignInConfig.airPrinterUrlStr]];[self.airPrinterController printToPrinter:airPrinter completionHandler:completionHandler];
}

在检查完毕后,即可调用上面的代码完成打印。同样的,这里的UIPrinter对象也是由之前的absoluteString构建而成。
打印相关的代理方法见UIPrintInteractionControllerDelegate,这里就不再赘述了,可以用其来控制一些打印中的流程和状态,这个代理方法是跟随UIPrintInteractionController而来,iOS8以前的版本也都可以使用。

参考链接:
airPrint苹果官方参考资料

<完>

AirPrint: 无交互的后台打印实现(Print without UI,iOS8+)相关推荐

  1. 批量打印--不展现直接后台打印

    批量打印--不展现直接后台打印(跳过手动触发打印) 实现效果: 客户经常想要实现多个报表批量打印(applet打印),并且不对报表进行展现(不手动点击打印触发),直接进行APPLET打印操作. 解决思 ...

  2. 操作无法完成后台打印程序无法运行

    同事反映原共享的打印机无法打印.我删除重新添加时系统提示 操作无法完成后台打印程序无法运行.于是我打开服务找到print spooler服务进程设置自动开启后重新添加问题依旧.在网上查到的方法是 病毒 ...

  3. [Web] [微信小程序-云开发] 商城 无服务器 加后台管理

    [Web] [微信小程序-云开发] 商城 无服务器 加后台管理 说明: 目前云开发仅针对认证后的公众号使用(每年300的费用那个) wxapp-mall-clouddb 前言 如何使用 更多说明 功能 ...

  4. 打印服务Print Spooler开启后自动关闭

    今天碰到print spooler关闭致使共享打印机无法打印的问题,虽然解决了,但还想更深入的了解一下这个服务,于是转载了这篇文章. 今一hp1010打印机无法打印,一看在打印机设置里空空如也啊,看不 ...

  5. 服务器调用虚拟打印机,请教:虚拟打印机和后台打印的实现

    需求: 开发一个虚拟打印机,提供给客户端使用.客户端使用这个虚拟打印机生成文档保存内打印容和设置好的打印选项(打印机选项和文档选项等)(这里称这些打印文档为虚拟打印结果). 服务端要能够在后台将客户端 ...

  6. 解决WINDOWS无法打开“添加打印机”,本地后台打印程序服务没有运行

    刚装好Windows 7发现HP还没提供1020PLUS的打印机驱动,无法使用打印机,于是想系统会不会带了打印机驱动呢?所以进入添加打印机,点击添加打印机却发现如下提示:解决WINDOWS无法打开&q ...

  7. 分享一个无水印的web打印组件

    转自张善友大牛的博客http://www.cnblogs.com/shanyou/p/3185111.html 应用web化,不论对开发商,还是对用户来说,实在是一种很经济的选择,因为基于web的应用 ...

  8. Android自定义后台打印服务

    接前一篇文章(Android调用系统默认打印机并反射获取打印任务状态 https://blog.csdn.net/yan1348/article/details/90666657)所说,完全按照系统默 ...

  9. python批量打印excel 按照顺序_从txt文件写入excel2007,后台打印顺序正常,但是打开excel实际数据没有按照顺序排列...

    openpyxl的版本是:openpyxl-2.5.0a1 我的目的是将txt中的文本写入excel中,其实是一个自己想实现的一个小功能 但是从txt文件写入excel2007,后台打印顺序正常,但是 ...

最新文章

  1. Python之父退休,C语言之父与世长辞,各大编程语言创始人现状盘点
  2. 打工人,从 JMM 透析 volatile 与 synchronized 原理
  3. c#如何将多个json合并_合并两个c#对象(json)列表作为父级子级
  4. 利用Java上手微服务架构
  5. php页面生成耗时分析
  6. DDS发生器的verilog实现(三)
  7. Android学习之高德地图的通用功能开发步骤(二)
  8. 从“小众”到“首选”,推动云原生产业落地华为云作用几何?
  9. asm数据文件迁移(os–asm)
  10. scala下划线的用法
  11. 25.TCP/IP 详解卷1 --- SNMP:简单网络管理协议
  12. 2021年1月PMP考试改版
  13. URL和Socket
  14. 广告投放媒体发展简史
  15. 视频直播的购物平台,网站,app
  16. Word 标题前面的黑点
  17. 【服务器】本地运行成功,但服务器上运行却显示错误500
  18. 全球及中国泵真空系统行业发展战略与十四五布局规划报告2022版
  19. cisco packet tracer_交换机配置/mac地址表(图解version:8+)
  20. windows中 mysql修改密码

热门文章

  1. UIGestureRecognizer与UIButton Action在同一界面冲突的问题
  2. Hacking techniques automation
  3. Linux 关闭桌面方法
  4. flex datagrid 导出csv
  5. 【转】hadoop深入研究:(十一)——序列化与Writable实现
  6. zookeeper在windows上安装和配置
  7. vue-cli 相同页面的跳转,但路由参数不同的情况下 组件状态没有更新的问题是为什么 如何解决
  8. ElementUI在el-table基础上进行导出.xls表格操作
  9. Github用户注册流程
  10. webpack常用的三种JS压缩插件