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

前言: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 UIPrintInfoOrientationLandscape

    printInfo.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 interactions
            self.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苹果官方参考资料

<完>

时间: 2024-10-01 01:58:26

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

让Win2003自我管理后台打印

打印|后台 如果对windows后台打印功能管理不当的话,有时不但不会提高系统的运行效率,反而会影响打印机的输出速度.为了有效提高打印效率,我们必须对系统的后台打印功能进行合适管理.以下介绍几种方法. 巧移位置,高效应对大批量作业 后台打印功能在默认状态下,会自动将接受到的打印作业,按照打印作业执行时间的先后顺序,依次缓存到Windows 2003系统中的"%systemroot%\system32\spool\printers"目录中,之后后台打印功能会自动对当前打印机的工作状态进行

跟后台打印程序系统服务通讯时出现错误的解决方法_win服务器

事件类型:      警告事件来源:      TermServDevices事件种类:      无事件 ID:      1114日期:          2006-12-19事件:          15:50:17用户:          N/A计算机:      描述:跟后台打印程序系统服务通讯时出现错误.请打开服务管理单元,确认后台打印程序服务是否在运行.-----------------------------------------------------------------

利用WebBrowser彻底解决Web打印问题(包括后台打印)_javascript技巧

抱着"取之于众 服务于众"的思想,我总结了一下,把它拿到网上来与大家分享,希望能帮助遇到类似问题的朋友. 我主要使用了IE内置的WebBrowser控件,无需用户下载和安装.WebBrowser有很多功能,除打印外的其他功能就不再赘述了,你所能用到的打印功能也几乎全部可以靠它完成,下面的问题就是如何使用它了.先说显示后打印,后面说后台打印. 1.首先引入一个WebBrowser在需要打印的页面,可以直接添加: <object id="WebBrowser" c

跟后台打印程序系统服务通讯时出现错误解决方法_win服务器

事件类型:      警告 事件来源:      TermServDevices 事件种类:      无 事件 ID:      1114 日期:          2006-12-19 事件:          15:50:17 用户:          N/A 计算机:      YONGFA365 描述: 跟后台打印程序系统服务通讯时出现错误.请打开服务管理单元,确认后台打印程序服务是否在运行. ----------------------------------------------

如何在Word 2013中使用后台打印文档功能

通过使用后台打印功能,可以实现在打印文档的同时继续编辑该Word2013文档,否则只能在完成打印任务后才能进行编辑.在Word2013中启用后台打印功能的步骤如下所述: 第1步,打开Word2013文档窗口,依次单击"文件"→"选项"命令,如图2013041821所示. 图2013041821 单击"选项"命令 第2步,打开"Word选项"对话框,切换到"高级"选项卡.在"打印"区域选中

在Word 2007中使用后台打印文档功能

通过使用后台打印功能,可以实现在打印文档的同时继续编辑该Word2007文档,否则只能在完成打印任务后才能进行编辑.在Word2007中启用后台打印功能的步骤如下所述: 第1步,打开Word2007文档窗口,依次单击"Office按钮"→"Word选项"按钮,如图2012040213所示. 图2012040213 单击"Word选项"按钮 第2步,打开"Word选项"对话框,切换到"高级"选项卡.在&quo

在Word 2010中使用后台打印文档功能

通过使用后台打印功能,可以实现在打印文档的同时继续编辑该Word 2010文档,否则只能在完成打印任务后才能进行编辑. 在Word 2010中启用后台打印功能的步骤如下所述: 第1步,打开Word 2010文档窗口,依次单击"文件"→"选项"命令,如图2011121111所示. 图2011121111 单 击"选项"命令 第2步,打开"Word选项"对话框,切换到"高级"选项卡.在"打印"

Win7系统打印机不能打印提示“print spooler错误”的解决方法

  Win7系统打印机不能打印提示"print spooler错误"的解决方法         具体步骤如下: 一.Windows无法启动方法 1.打开电脑左下角[开始]菜单,找到[运行]选项,点击打开; 2.在弹出的运行对话框输入 services.msc 命令,点击确定; 3.进入服务项界面,找到 print spooler 服务右键点击选择[属性]选项,进入属性对话框,点击上方[依赖关系]; 4.在依赖关系栏里,找到[print spooler]服务所依赖的相关服务rpc; 5.

一个很简单的jquery+xml+ajax的无刷新树结构(无css,后台是c#)_jquery

复制代码 代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data.Linq; using System.Xml; using System.Xml.Linq; namespace WebApplication3 { public