
作者:dustturtle
前言: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 s
hared UIPrintInteractionController!");
return;
}
controller.delegate = self;
UIPrintInfo *printInfo = [UIPrintInfo printInfo];
printInfo.outputType = UIPrintInfoOutputPhoto;
printInfo.orientation = UIPrintInfoOrientationPortrait; // UIPrintInfoOrientationPortrait or UIPrintInfoOrientationLandscape
printInfo.jobName = @"AirPrintWechatSize";
controller.printInfo = printInfo;
UIImage *printImage = [UIImage imageNamed:@"7.jpg"];
controller.printingItem = printImage;
void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) = ^(UIPrintInteractionController *printController, BOOL completed, NSError *error) {
};
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);
void (^completionHandler)(UIPrinterPickerController *, BOOL, NSError *) = ^(UIPrinterPickerController *printController, BOOL userDidSelect, NSError * err) {
if (userDidSelect)
{
// save the urlString and Printer name, do your UI interactions
GSignInConfig.airPrinterUrlStr = controller.selectedPrinter.URL.absoluteString;
GSignInConfig.airPrinterName = 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
{
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;
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蘋果官方參考資料
<完>