iOS 使用airPrint实现手机打印功能
项目中有需求需要做一个手机云打印的功能,于是收集并整理了一些管理iOS端airPrint相关的资料如下
什么是AirPrint
其实就是将iOS(iphone,ipad)上的内容,使用支持AirPrint的打印机打印出来。打印过程无线控制, 非常方便。
资料参考
学习资料参考官方demo 下载地址:https://developer.apple.com/airprint/
github上面提供的demo 下载地址:https://github.com/lsh-Alan/AirPrint/
Printer Simulator,使用打印模拟器进行测试
如果有打印机,可以直接连接wifi进行打印,如果没有,下载官方的打印机模拟器Additional Tools for Xcode【选择适合的xcode工具】 下载地址:https://developer.apple.com/download/all/
打印机能打印的内容范围
- an array of ready-to-print images and PDF documents: 一组图片文件和PDF文件。
- a single image or PDF document: 一张图片或是一个pdf文件。、
- an instance of any of the built-in print formatter classes: 打印格式化者的实例。(简单文本,html文档,某些View显示的内容)。
- a custom page renderer: 自定义页渲染者。
API介绍
AirPrint的api包含 eight classes and one protocol。 下图是它们之间的关系。(下面这张图明白了, 那你基本就掌握了)。
AirPrint相关类
UIPrintInteractionController 属性:
- UIPrintInfo *printInfo: 打印任务的信息。
- UIPrintPaper * printPaper : 打印内容的区域。
- delegate: 遵守UIPrintInteractionControllerDelegate 协议的代理。
- 最重要的就是制定需要打印的内容: printingItem , printingItems, printFormatter, printPageRenderer。 四个属性都是用来指定要打印的内容的。 这四个参数是互斥的, 也就是说只要一个赋值, 其他三个参数就得是nil. 很容易理解,一个打印任务, 不能同时干多个活呀。 这里如果使用 swift的枚举,就很容易理解了
需要打印的内容与相应参数的对应方式
打印流程
- 创建 UIPrintInteractionController 实例。
- 创建UIPrintInfo 实例。 并 配置参数 output type(输出类型), print orientation(打印方向), job name(打印工作标识), 然后赋值给UIPrintInteractionController 实例的 printInfo属性。
- 给delegate 属性赋值, 赋的值必须遵守 UIPrintInteractionControllerDelegate 协议。 这个代理可以 响应 printing options界面的显示和消失, 打印工作的开始和结束 等。
- 指定要打印的内容。 也就是指定 printingItem , printingItems, printFormatter, printPageRenderer. 参数的其中一个。
- 当你使用 printPageRenderer. 时情况会复杂一些。 你可以绘制每一页的header, footer, 内容。 这是你需要自己计算页数。 另外, 你也可以创建一个或多个 UIPrintFormatter实例, 通 过 addPrintFormatter:startingAtPageAtIndex: 或者 printFormatters参数 赋值给 printPageRenderer.实例。 这种情况下不需要自己计算多少页。
- 最后就是显示显示出printing options 界面了。 方法:
在iPad上: presentFromBarButtonItem:animated:completionHandler:
或者 presentFromRect:inView:animated:completionHandler:;
在手机上: presentAnimated:completionHandler:
说了这么多, 理论知识就介绍的差不多了, 下面通过代码演示具体实现。
Printing Printer-Ready Content (打印准备好的内容)
AirPrint可以直接打印一些内容。 这些内容是 NSData, NSURL, UIImage, and ALAsset 类的实例, 但是这些实例的内容, 或者引用的类型(NSURL)必须是 image 或者pdf.
对于 image来说, NSData, NSURL, UIImage, and ALAsset 类型都可以的。 对于PDF, 只能使用 NSData, NSURL。 然后需要将这些数据实例直接赋值 给 UIPrintInteractionController实例的 printingItem 或者 printingItems 属性。
打印pdf:
- (IBAction)printContent:(id)sender {
UIPrintInteractionController *pic = [UIPrintInteractionController sharedPrintController];
if (pic && [UIPrintInteractionController canPrintData: self.myPDFData] ) {
pic.delegate = self;
UIPrintInfo *printInfo = [UIPrintInfo printInfo];
printInfo.outputType = UIPrintInfoOutputGeneral;
printInfo.jobName = [self.path lastPathComponent];
printInfo.duplex = UIPrintInfoDuplexLongEdge;
pic.printInfo = printInfo;
pic.showsPageRange = YES;
pic.printingItem = self.myPDFData;
void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) =
^(UIPrintInteractionController *pic, BOOL completed, NSError *error) {
self.content = nil;
if (!completed && error)
NSLog(@"FAILED! due to error in domain %@ with error code %u",
error.domain, error.code);
};
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[pic presentFromBarButtonItem:self.printButton animated:YES
completionHandler:completionHandler];
} else {
[pic presentAnimated:YES completionHandler:completionHandler];
}
}
Using Print Formatters (打印格式化者)
系统提供了三个 Print Formatters类, 分别是:
- UIViewPrintFormatter—automatically lays out the content of a view over multiple pages. To obtain a print formatter for a view, call the view’s viewPrintFormatter method. Not all built-in UIKit classes support printing. Currently, only the view classes UIWebView, UITextView, and MKMapView know how to draw their contents for printing. View formatters should not be used for printing your own custom views. To print the contents of a custom view, use a UIPrintPageRenderer instead.
- UISimpleTextPrintFormatter—automatically draws and lays out plain-text documents. This formatter allows you to set global properties for the text, such a font, color, alignment, and line-break mode.
- UIMarkupTextPrintFormatter—automatically draws and lays out HTML documents.
英文介绍已经很详细了, 就不啰嗦了, 直接展示出打印HTML文档的代码:
- (IBAction)printContent:(id)sender {
UIPrintInteractionController *pic = [UIPrintInteractionController sharedPrintController];
pic.delegate = self;
UIPrintInfo *printInfo = [UIPrintInfo printInfo];
printInfo.outputType = UIPrintInfoOutputGeneral;
printInfo.jobName = self.documentName;
pic.printInfo = printInfo;
UIMarkupTextPrintFormatter *htmlFormatter = [[UIMarkupTextPrintFormatter alloc]
initWithMarkupText:self.htmlString];
htmlFormatter.startPage = 0;
htmlFormatter.contentInsets = UIEdgeInsetsMake(72.0, 72.0, 72.0, 72.0); // 1 inch margins
pic.printFormatter = htmlFormatter;
pic.showsPageRange = YES;
void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) =
^(UIPrintInteractionController *printController, BOOL completed, NSError *error) {
if (!completed && error) {
NSLog(@"Printing could not complete because of error: %@", error);
}
};
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[pic presentFromBarButtonItem:sender animated:YES completionHandler:completionHandler];
} else {
[pic presentAnimated:YES completionHandler:completionHandler];
}
}
将UIWebView 界面上显示的内容打印出来。
- (void)printWebPage:(id)sender {
UIPrintInteractionController *controller = [UIPrintInteractionController sharedPrintController];
void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) =
^(UIPrintInteractionController *printController, BOOL completed, NSError *error) {
if(!completed && error){
NSLog(@"FAILED! due to error in domain %@ with error code %u",
error.domain, error.code);
}
};
UIPrintInfo *printInfo = [UIPrintInfo printInfo];
printInfo.outputType = UIPrintInfoOutputGeneral;
printInfo.jobName = [urlField text];
printInfo.duplex = UIPrintInfoDuplexLongEdge;
controller.printInfo = printInfo;
controller.showsPageRange = YES;
UIViewPrintFormatter *viewFormatter = [self.myWebView viewPrintFormatter];
viewFormatter.startPage = 0;
controller.printFormatter = viewFormatter;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[controller presentFromBarButtonItem:printButton animated:YES completionHandler:completionHandler];
}else
[controller presentAnimated:YES completionHandler:completionHandler];
}
参考来源
https://www.jianshu.com/p/7cff5d89f3ac
https://www.jb51.net/article/209487.htm
转载请标注来源:https://www.cnblogs.com/qqcc1388/p/16373547.html