使用UIPrintInteractionController并行调度多打印任务失败的问题咨询
能否使用UIPrintInteractionController并行调度多个打印任务?
结论
UIPrintInteractionController是单例实现(通过shared属性获取唯一实例),无法直接并行处理多个打印任务,同一时间仅能执行一个打印任务。
问题分析
你当前的代码存在两个核心问题:
- 多次异步调用
PrintPdfDocument时,每次都复用同一个UIPrintInteractionController.shared实例,后续任务会覆盖前序任务的配置(如printingItems、printInfo),且单例同一时间只能处理一个print(to:)请求,导致仅第一个任务能正常执行。 - UIPrintInteractionController属于UI相关类,所有操作必须在主队列执行,你在全局后台队列调用会触发潜在的线程安全问题。
解决方案:串行化打印任务
将所有打印任务串行执行,确保一个任务完成后再启动下一个,同时将操作移至主队列:
方式1:递归链式调用
// 定义待打印任务列表 let printDocuments = [data1, data2, data3] var currentPrintIndex = 0 func executeNextPrintJob() { guard currentPrintIndex < printDocuments.count else { return } let documentData = printDocuments[currentPrintIndex] currentPrintIndex += 1 // 切换至主队列执行打印操作 DispatchQueue.main.async { let printController = UIPrintInteractionController.shared // 配置打印信息 let printInfo = UIPrintInfo(dictionary: nil) printInfo.jobName = "Print Job \(currentPrintIndex)" printController.printInfo = printInfo printController.showsPageRange = true // 注意:printingItems要求为[Any]类型,需将Data包装为数组 printController.printingItems = [documentData] printController.print(to: defaulttprinter, completionHandler: { (_, completed, error) in if completed { print("打印成功:\(printInfo.jobName)") } else { if let error = error { print("打印失败:\(error.localizedDescription)") } else { print("打印被取消:\(printInfo.jobName)") } } // 当前任务完成后,启动下一个打印任务 executeNextPrintJob() }) } } // 启动打印任务链 executeNextPrintJob()
方式2:使用串行OperationQueue
let printQueue = OperationQueue() printQueue.maxConcurrentOperationCount = 1 // 设置为串行队列 for (index, data) in [data1, data2, data3].enumerated() { let printOperation = BlockOperation { DispatchQueue.main.sync { let printController = UIPrintInteractionController.shared let printInfo = UIPrintInfo(dictionary: nil) printInfo.jobName = "Print Job \(index + 1)" printController.printInfo = printInfo printController.showsPageRange = true printController.printingItems = [data] let semaphore = DispatchSemaphore(value: 0) printController.print(to: defaulttprinter, completionHandler: { (_, completed, error) in // 处理打印结果 semaphore.signal() }) semaphore.wait() } } printQueue.addOperation(printOperation) }
补充说明
如果需要向不同打印机发送任务,UIPrintInteractionController的单例特性仍然无法支持并行,此时可以直接使用UIPrinter的print(_:completionHandler:)方法,但注意:同一台物理打印机本身无法并行处理多个任务,最终仍需串行执行。
内容的提问来源于stack exchange,提问作者Abhishek
相关产品推荐
相关产品推荐

