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

Swift中如何将默认打印机保存至UserDefaults?

解决UIPrinter无法保存到UserDefaults的问题

嘿,这个问题我之前做iOS打印功能的时候也遇到过——UIPrinter确实没法直接存进UserDefaults,不过有两个靠谱的解决方案,能帮你搞定默认打印机的保存和恢复:

方法一:利用UIPrinter的URL属性序列化

UIPrinter本身不支持直接存入UserDefaults,但它提供了一个url属性,这个URL是可序列化的,完全可以安全存储。步骤很简单:

保存选中的打印机

当用户在UIPrinterPickerController中选中打印机后,我们把它的URL存进UserDefaults:

if userDidSelect {
    if let defaultPrinter = printerPicker.selectedPrinter {
        UserDefaults.standard.set(defaultPrinter.url, forKey: "DefaultPrinterURL")
    }
}

读取并恢复打印机

下次需要使用默认打印机时,从UserDefaults取出URL,再通过系统方法异步恢复UIPrinter实例:

if let printerURL = UserDefaults.standard.url(forKey: "DefaultPrinterURL") {
    UIPrinter.printer(with: printerURL) { restoredPrinter in
        guard let printer = restoredPrinter else {
            // 打印机不可用,可能需要重新让用户选择
            return
        }
        // 这里就可以用恢复后的printer直接发起打印了
        self.printWithDefaultPrinter(printer)
    }
}

这个方法的好处是系统会自动验证URL对应的打印机是否还可用,避免使用已经离线或被移除的设备。

方法二:通过NSKeyedArchiver归档存储

UIPrinter遵循NSSecureCoding协议,所以我们可以把它归档成Data,再存入UserDefaults:

保存打印机

if userDidSelect {
    if let defaultPrinter = printerPicker.selectedPrinter {
        do {
            let printerData = try NSKeyedArchiver.archivedData(
                withRootObject: defaultPrinter,
                requiringSecureCoding: true
            )
            UserDefaults.standard.set(printerData, forKey: "DefaultPrinterData")
        } catch {
            print("归档打印机失败:\(error.localizedDescription)")
        }
    }
}

恢复打印机

if let printerData = UserDefaults.standard.data(forKey: "DefaultPrinterData") {
    do {
        if let restoredPrinter = try NSKeyedUnarchiver.unarchivedObject(
            ofClass: UIPrinter.self,
            from: printerData
        ) {
            // 恢复成功,使用打印机
            self.printWithDefaultPrinter(restoredPrinter)
        }
    } catch {
        print("解归档打印机失败:\(error.localizedDescription)")
    }
}

这个方法会保存打印机的更多细节,但如果打印机的网络信息发生变化,可能会出现恢复失败的情况,所以更推荐第一种方法。

直接打印(无需预览弹窗)

恢复默认打印机后,你可以直接用UIPrintInteractionController发起打印,跳过预览弹窗:

func printWithDefaultPrinter(_ printer: UIPrinter) {
    let printInfo = UIPrintInfo.printInfo()
    printInfo.outputType = .general // 根据你的打印内容调整类型
    printInfo.jobName = "我的打印任务"
    
    let printController = UIPrintInteractionController.shared
    printController.printInfo = printInfo
    printController.printingItem = // 这里传入你的打印内容,比如PDF Data、UIImage等
    printController.printer = printer
    
    // 直接发送打印任务,不显示预览
    printController.print(to: printer, completionHandler: { (_, success, error) in
        if let error = error {
            print("打印出错:\(error.localizedDescription)")
        } else if success {
            print("打印任务已发送")
        }
    })
}

内容的提问来源于stack exchange,提问作者anas.p

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:13:37