作者: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蘋果官方參考資料
<完>