macOS Swift将HTML转PDF遇PMSessionBeginCGDocumentNoDialog() -61错误求助
Swift将HTML转为PDF时PMSessionBeginCGDocumentNoDialog()返回-61错误的修复方案
嘿,作为Swift新手想用HTML生成PDF发票却碰到这个问题,确实挺闹心的!我帮你梳理下问题根源,再给你调整后的可用代码:
问题根源分析
你碰到的-61错误虽然提示权限,但核心问题其实不是沙箱——你的代码里只给了保存目录,没指定具体的PDF文件名,系统根本不知道要把文件存成啥,自然写入失败;另外用NSTextField承载HTML富文本,也容易出现渲染不全或打印会话的额外问题;至于-1002错误,大概率是HTML里引用了外部网络资源(比如图片、样式)加载失败导致的,先解决PDF写入的核心问题再说。
修复后的代码
func makePDF(markup: String) { // 1. 生成带时间戳的唯一PDF文件名,避免覆盖 let documentsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] let pdfFileURL = documentsDir.appendingPathComponent("invoice_\(Date().timeIntervalSince1970).pdf") // 2. 配置打印信息,明确纸张尺寸和保存路径 let printOpts: [NSPrintInfo.AttributeKey: Any] = [ .jobDisposition: NSPrintInfo.JobDisposition.save, .jobSavingURL: pdfFileURL, .paperSize: NSPaperSize.A4 ] let printInfo = NSPrintInfo(dictionary: printOpts) printInfo.topMargin = 20.0 printInfo.leftMargin = 20.0 printInfo.rightMargin = 20.0 printInfo.bottomMargin = 20.0 guard let htmlData = markup.data(using: .utf8) else { print("无法将HTML转为UTF8格式数据") return } // 3. 直接用PDFKit渲染富文本,绕开NSPrintOperation的坑 do { let attrStr = try NSAttributedString( data: htmlData, options: [ .documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue ], documentAttributes: nil ) // 设置PDF页面尺寸和可打印区域 let pageSize = printInfo.paperSize let pageRect = NSRect(x: 0, y: 0, width: pageSize.width, height: pageSize.height) let printableRect = printInfo.printableRect // 生成PDF数据 let pdfData = NSMutableData() UIGraphicsBeginPDFContextToData(pdfData, pageRect, nil) let textRange = NSRange(location: 0, length: attrStr.length) attrStr.draw(with: printableRect, options: .usesLineFragmentOrigin, range: textRange, context: nil) UIGraphicsEndPDFContext() // 写入到指定文件 do { try pdfData.write(to: pdfFileURL) print("PDF生成成功!路径:\(pdfFileURL.path)") } catch { print("写入PDF文件失败:\(error.localizedDescription)") } } catch { print("HTML转富文本失败:\(error.localizedDescription)") } }
关键改动说明
- 指定完整文件名:原来只传了目录URL,现在生成带时间戳的唯一文件名,让系统明确写入目标
- 改用PDFKit直接渲染:放弃
NSTextField + NSPrintOperation的方式,直接用PDF上下文渲染富文本,避免打印会话的权限和渲染bug - 明确纸张尺寸:添加A4纸张配置,适配标准发票的排版需求
- 完善错误处理:添加
guard和do-catch,方便你排查每一步的问题
额外建议
- 关于
-1002错误:检查你的HTML里是否有外部网络资源(比如<img>标签的网络链接),如果有,记得在Info.plist里配置NSAppTransportSecurity允许HTTP资源,或者改用HTTPS链接 - 权限验证:如果还是碰到权限问题,可以打印
pdfFileURL.path,手动去这个目录看看能不能创建文件,确认目录的读写权限
内容的提问来源于stack exchange,提问作者Luchspeter
相关产品推荐
相关产品推荐

