Swift Cocoa程序Sonoma系统中printOperation无法运行求助
我有一个用Swift编写的Cocoa打印NSView程序,在Monterey系统运行正常,但到了Sonoma系统里打印面板完全不显示,同时弹出以下错误:
Failed to connect (genericPrinterImage) outlet from (PMPrinterSelectionController) to (NSImageView): missing setter or instance variable
Failed to connect (otherPrintersLabel) outlet from (PMPrinterSelectionController) to (NSTextField): missing setter or instance variable
Failed to connect (localPrintersLabel) outlet from (PMPrinterSelectionController) to (NSTextField): missing setter or instance variable
Failed to connect (genericPrinterImage) outlet from (PMPrinterSelectionController) to (NSImageView): missing setter or instance variable
对应的代码实现如下:
func createPrintOperation() { let printOpts: [NSPrintInfo.AttributeKey: Any] = [ .headerAndFooter: false, .orientation: NSPrintInfo.PaperOrientation.portrait ] let printInfo = NSPrintInfo(dictionary: printOpts) printInfo.leftMargin = 0 printInfo.rightMargin = 0 printInfo.topMargin = 0 printInfo.bottomMargin = 0 printInfo.horizontalPagination = .fit printInfo.verticalPagination = .automatic printInfo.isHorizontallyCentered = true printInfo.isVerticallyCentered = true printInfo.scalingFactor = 1.0 printInfo.paperSize = NSMakeSize(612, 792) // Letter size // Create a print operation with the view you want to print , myPrintView is a NSView let printOperation = NSPrintOperation(view: myPrintView, printInfo: printInfo) // Configure the print panel printOperation.printPanel.options.insert(NSPrintPanel.Options.showsPaperSize) printOperation.printPanel.options.insert(NSPrintPanel.Options.showsOrientation) // Set the job title for the print operation let jobTitle = fact.nom_complet_f.replacingOccurrences(of: " ", with: "") printOperation.jobTitle = jobTitle // Run the print operation printOperation.run() }
问题分析
这些错误是Sonoma系统中打印面板的内部控件连接失败导致的,本质是系统打印框架的资源加载出现冲突,或是自定义的打印配置干扰了系统默认组件的初始化流程。
解决方案
方案1:简化PrintInfo配置,使用系统默认实例
过度自定义PrintInfo可能触发系统打印面板的初始化异常,尝试简化配置并使用系统默认实例:
func createPrintOperation() { // 使用系统默认的PrintInfo实例 let printInfo = NSPrintInfo.shared printInfo.leftMargin = 0 printInfo.rightMargin = 0 printInfo.topMargin = 0 printInfo.bottomMargin = 0 printInfo.horizontalPagination = .fit printInfo.verticalPagination = .automatic printInfo.isHorizontallyCentered = true printInfo.isVerticallyCentered = true printInfo.scalingFactor = 1.0 printInfo.paperSize = NSMakeSize(612, 792) // Letter size let printOperation = NSPrintOperation(view: myPrintView, printInfo: printInfo) // 直接赋值面板选项而非插入,避免冗余配置 printOperation.printPanel.options = [.showsPaperSize, .showsOrientation] let jobTitle = fact.nom_complet_f.replacingOccurrences(of: " ", with: "") printOperation.jobTitle = jobTitle // 主线程异步运行,避免阻塞UI初始化 DispatchQueue.main.async { printOperation.run() } }
方案2:排查项目资源冲突
- 检查项目中是否存在自定义的
PMPrinterSelectionController类或同名XIB文件,这类资源会覆盖系统默认组件 - 清理项目的Derived Data,重新编译运行
方案3:手动初始化打印面板
绕过默认的打印面板创建逻辑,手动初始化系统标准打印面板:
func createPrintOperation() { let printOpts: [NSPrintInfo.AttributeKey: Any] = [ .headerAndFooter: false, .orientation: NSPrintInfo.PaperOrientation.portrait ] let printInfo = NSPrintInfo(dictionary: printOpts) // 保留原有printInfo配置 let printOperation = NSPrintOperation(view: myPrintView, printInfo: printInfo) // 手动创建系统默认打印面板 let printPanel = NSPrintPanel() printPanel.options = [.showsPaperSize, .showsOrientation] printOperation.printPanel = printPanel let jobTitle = fact.nom_complet_f.replacingOccurrences(of: " ", with: "") printOperation.jobTitle = jobTitle printOperation.run() }
内容的提问来源于stack exchange,提问作者S Lareau

