UIPrintInteractionController's printToPrinter crash in 'lookupLastUsedPrinter' API call

234 views Asked by At
  • We are seeing following crash in our codebase (iOS 15) with following call stack in UIPrintInteractionController.
  • Could anyone please help with your inputs on how we can address following "UIPrintInteractionController's printToPrinter api crash"

Crash stack

uncaught ObjC exception, reason: -[PKPrinter _internalPrinter]: unrecognized selector sent to instance 

Last Exception Backtrace:
2   libobjc.A.dylib                      objc_exception_throw (??:0)w + 60 
3   CoreFoundation                       __CFOAInitializeNSObject (??:0)3 + 1535940 
4   CoreFoundation                       ___forwarding___ (??:0)3 + 188056 
5   CoreFoundation                       __CFRunLoopDoTimers (??:0)0 + 96 
6   UIKitCore                            __51-[UIPrintPanelViewController lookupLastUsedPrinter]_block_invoke (??:0)5 + 15751960 
7   UIKitCore                            -[UIPrintPanelViewController loadView] (??:0)5 + 15735732 
8   UIKitCore                            __88-[UIPrintInteractionController _generatePDFInRange:useFullRange:withQuality:completion:]_block_invoke (??:0)5 + 15935408 
9   UIKitCore                            -[UIPrintInteractionController printToPrinter:completionHandler:] (??:0)5 + 15915992 
10  UIKitCore                            -[UIPrintInteractionController _completePrintPageWithError:] (??:0)5 + 15960488 
11  UIKitCore                            -[UIPrintInteractionController printToPrinter:completionHandler:] (??:0)5 + 15915780 

Codebase that resulted above crash

UIPrintInteractionController *printController = [UIPrintInteractionController sharedPrintController];
UIPrintInteractionCompletionHandler completionHandler = ^(UIPrintInteractionController *printControllerT, BOOL completed, NSError *error) {
  [printControllerT setDelegate:nil];                          
};
[printController setDelegate:printDelegate];
[printController setPrintingItem:rurlPrintJob];                    
[printController presentAnimated:YES completionHandler:completionHandler];

More info

  • meanwhile I have found one apple thread where its mentioned that “App Crash when using print of UIPrintInteractionController” ==>https://developer.apple.com/forums/thread/689876.
  • Above thread suggested to use printer.contactPrinter instead of printerController.print.Since our current codebase used default iOS codepath(printToPrinter) with ‘[[UIPrintInteractionController sharedPrintController]presentAnimated:YES completionHandler:completionHandler]]’ api call , I am not able to apply this suggestion in current codebase.
1

There are 1 answers

0
lxbndr On

This looks like an internal iOS issue. PKPrinter is a private class, but _iternalPrinter is a private selector from the public class UIPrinter. Something got messy under the hood.

There is a workaround. Try setting fresh UIPrintInfo before presenting print UI:

UIPrintInteractionController *printController = [UIPrintInteractionController sharedPrintController];
UIPrintInteractionCompletionHandler completionHandler = ^(UIPrintInteractionController *printControllerT, BOOL completed, NSError *error) {
  printController.delegate = nil;                          
};
printController.delegate = printDelegate;
printController.printInfo = [UIPrintInfo printInfo]; // <- Fixes the crash
printController.printingItem = rurlPrintJob;
[printController presentAnimated:YES completionHandler:completionHandler];

We are observing this crash for a while and finally were able to reproduce it. In our case, we have two different code locations using UIPrintInteractionController. First of them assigns UIPrintInfo with various adjustments, like job name and output type. The second place simply sets printingItem and presents UI, just like in your sample code. But print attempts are not isolated, and it looks like some internals are getting corrupted in some scenarios.