import Cocoa import PDFKit import UniformTypeIdentifiers enum PrintService { static func print(urls: [URL]) { guard !urls.isEmpty else { return } for url in urls { let accessed = url.startAccessingSecurityScopedResource() defer { if accessed { url.stopAccessingSecurityScopedResource() } } printFile(at: url) } } private static func printFile(at url: URL) { let type = UTType(filenameExtension: url.pathExtension) ?? .data if type.conforms(to: .pdf), let document = PDFDocument(url: url) { printPDF(document) } else if type.conforms(to: .image), let image = NSImage(contentsOf: url) { printImage(image) } else if type.conforms(to: .plainText) || type.conforms(to: .text), let text = try? String(contentsOf: url, encoding: .utf8) { printText(text) } else if type.conforms(to: .rtf), let data = try? Data(contentsOf: url), let attributed = NSAttributedString(rtf: data, documentAttributes: nil) { printAttributedText(attributed) } else if type.conforms(to: .html), let data = try? Data(contentsOf: url), let attributed = NSAttributedString(html: data, documentAttributes: nil) { printAttributedText(attributed) } else { showUnsupportedAlert(for: url) } } private static func printPDF(_ document: PDFDocument) { let printInfo = configuredPrintInfo() guard let operation = document.printOperation( for: printInfo, scalingMode: .pageScaleToFit, autoRotate: true ) else { return } operation.run() } private static func printImage(_ image: NSImage) { let size = image.size guard size.width > 0, size.height > 0 else { return } let imageView = NSImageView(frame: NSRect(origin: .zero, size: size)) imageView.image = image imageView.imageScaling = .scaleProportionallyUpOrDown let operation = NSPrintOperation(view: imageView, printInfo: configuredPrintInfo()) operation.run() } private static func printText(_ text: String) { printAttributedText(NSAttributedString(string: text)) } private static func printAttributedText(_ text: NSAttributedString) { let textView = NSTextView(frame: NSRect(x: 0, y: 0, width: 612, height: 792)) textView.textStorage?.setAttributedString(text) textView.isEditable = false let operation = NSPrintOperation(view: textView, printInfo: configuredPrintInfo()) operation.run() } private static func configuredPrintInfo() -> NSPrintInfo { let printInfo = NSPrintInfo.shared.copy() as! NSPrintInfo let printerName = AppSettings.effectiveDefaultPrinter if let printer = NSPrinter(name: printerName) { printInfo.printer = printer } return printInfo } private static func showUnsupportedAlert(for url: URL) { let alert = NSAlert() alert.messageText = "Unsupported File" alert.informativeText = "\"\(url.lastPathComponent)\" cannot be printed." alert.alertStyle = .warning alert.addButton(withTitle: "OK") alert.runModal() } }