You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用UIPrintInteractionController并行调度多打印任务失败的问题咨询

能否使用UIPrintInteractionController并行调度多个打印任务?

结论

UIPrintInteractionController是单例实现(通过shared属性获取唯一实例),无法直接并行处理多个打印任务,同一时间仅能执行一个打印任务。

问题分析

你当前的代码存在两个核心问题:

  1. 多次异步调用PrintPdfDocument时,每次都复用同一个UIPrintInteractionController.shared实例,后续任务会覆盖前序任务的配置(如printingItems、printInfo),且单例同一时间只能处理一个print(to:)请求,导致仅第一个任务能正常执行。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 20:21:02