iOS 27: print(to:) silently drops every job after the first

The problem

On iOS 27, UIPrintInteractionController.print(to:completionHandler:) works on its first call in a process. Every subsequent call is accepted (print(to:) returns true and printInteractionControllerWillStartJob fires), but the completion handler is never invoked: nothing prints, didFinishJob never fires, no error is produced, and no job appears in Print Center.

I expected each call to submit an independent job and invoke its completion handler, as it does on iOS 26 and earlier with the identical binary.

Steps to reproduce

  1. Build an app that prints without the print panel, using a retained UIPrinter from UIPrinterPickerController.
  2. Submit a job:
let controller = UIPrintInteractionController.shared
let info = UIPrintInfo(dictionary: nil)
info.outputType = .general
info.jobName = "job-\(n)"
controller.printInfo = info
controller.printingItem = pdfData          // valid PDF, canPrint(data) == true
controller.delegate = self
let started = controller.print(to: savedPrinter) { _, completed, error in
    print("completion", completed, String(describing: error))
}
print("started", started)
  1. First job: started == true, both willStartJob and didFinishJob fire, the completion handler runs with completed == true, and the page prints.
  2. Submit a second job the same way, same process.
  3. started == true and willStartJob fires with printInfo.printerID populated and printPaper negotiated to the same values as the successful job. Then nothing. No didFinishJob, no completion handler, no error, no page, nothing in Print Center.
  4. A third job: print(to:) returns false synchronously, since the shared controller still considers job two in flight.

System information

  • iPad, iPadOS 27.0 developer beta 6
  • Built against iOS 26.2 SDK (Xcode 26.2). Same binary works on iOS 26.
  • Reproduced on two unrelated printers: Brother QL-820NWB and Canon MF420 Series.
  • Content is a small PDF (~11 to 13 KB); canPrintData: returns true.

Troubleshooting tried

  • Restarted the iPad and reinstalled the app. Each buys exactly one successful print before the failure returns.
  • Compared observable state between the working and hung jobs. Identical in every respect.
  • During a hang, printed the same content to the same printer from Files via the share sheet. Worked normally, including on repeat.
  • Paused in the debugger during the hang. No blocked thread; no PrintKit frame, XPC wait, or semaphore anywhere in bt all.
  • Called contactPrinter before each job on the retained printer. Returned true quickly, and the job still hung.
  • Implemented printInteractionControllerParentViewController(_:) in case a presentation context was missing. UIKit never calls it on this path.

Workaround

Creating a new UIPrintInteractionController per job resolves it completely. A long-lived instance the app creates itself fails exactly like .shared does, so the issue is reuse of a controller that has already run a job, not the shared singleton specifically.

Is per-job instantiation the supported pattern? The docs say the shared instance "represents a print job" but don't state whether a controller may be reused for a second job, and every sample I can find uses sharedPrintController with the present… methods rather than print(to:).

I'm having the same issue :(

iOS 27: print(to:) silently drops every job after the first
 
 
Q