Mac平台Swift获取打印进度及打印完成通知方法咨询
macOS 打印进度监听与完成提示实现方案
方案一:基于NSPrintOperation的系统集成方案
如果不需要完全自定义进度UI,直接复用系统进度面板并监听打印完成状态是最简便的方式:
- 创建并启动打印任务
// 配置打印信息 NSPrintInfo *printInfo = [NSPrintInfo sharedPrintInfo]; printInfo.printer = [NSPrinter printerWithName:@"你的打印机名称"]; // 可选,默认使用系统默认打印机 // 创建打印操作 NSPrintOperation *printOp = [NSPrintOperation printOperationWithView:yourPrintableView printInfo:printInfo]; printOp.delegate = self; printOp.showsProgressPanel = YES; // 开启系统自带的进度面板 // 启动打印 [printOp runOperation];
- 实现代理方法监听打印结果
#pragma mark - NSPrintOperationDelegate - (void)printOperationDidRun:(NSPrintOperation *)printOp success:(BOOL)success contextInfo:(void *)contextInfo { NSAlert *alert = [[NSAlert alloc] init]; if (success) { alert.messageText = @"打印完成"; alert.informativeText = @"文档已成功打印"; } else { alert.messageText = @"打印失败"; alert.informativeText = @"打印过程中出现错误或被取消"; } [alert addButtonWithTitle:@"确定"]; [alert runModal]; }
方案二:基于PrintCore的自定义进度监听
如果需要完全自定义进度显示(比如嵌入到自己的UI中),可以使用PrintCore的底层API监听打印作业状态:
- 导入依赖框架
#import <AppKit/AppKit.h> #import <PrintCore/PrintCore.h>
- 提交打印任务并添加作业监听器
// 获取目标打印机 PMPrinter printer; OSStatus status = PMPrinterCreateFromName((CFStringRef)[[NSPrintInfo sharedPrintInfo] printerName], &printer); if (status != noErr) return; // 创建打印会话 PMSession session; status = PMSessionCreate(kCFAllocatorDefault, &session); if (status != noErr) { PMPrinterRelease(printer); return; } // 添加作业状态监听器(回调函数处理状态变化) status = PMSessionAddPrintJobListener(session, printer, PrintJobStatusCallback, (__bridge void *)self); if (status != noErr) { PMSessionRelease(session); PMPrinterRelease(printer); return; } // 启动打印操作(和方案一的启动方式一致) NSPrintOperation *printOp = [NSPrintOperation printOperationWithView:yourPrintableView printInfo:[NSPrintInfo sharedPrintInfo]]; [printOp runOperation];
- 实现C语言回调函数处理状态与进度
void PrintJobStatusCallback(PMSession session, PMPrinter printer, PMJob job, PMJobStatus status, void *context) { // 切换到主线程更新UI dispatch_async(dispatch_get_main_queue(), ^{ __weak typeof(YourViewControllerClass) *weakVC = (__bridge typeof(YourViewControllerClass))context; switch (status) { case kPMJobStatusPrinting: { // 获取打印进度 CFIndex completedPages, totalPages; if (PMJobGetPageCounts(job, &completedPages, &totalPages) == noErr) { CGFloat progress = (CGFloat)completedPages / totalPages; // 更新自定义进度控件,比如: // weakVC.progressIndicator.doubleValue = progress; NSLog(@"打印进度:%.0f%%", progress * 100); } break; } case kPMJobStatusCompleted: { // 打印完成提示 NSAlert *alert = [[NSAlert alloc] init]; alert.messageText = @"打印完成"; alert.informativeText = @"文档已成功打印"; [alert addButtonWithTitle:@"确定"]; [alert runModal]; // 清理资源 PMSessionRemovePrintJobListener(session, printer, PrintJobStatusCallback, context); PMSessionRelease(session); break; } case kPMJobStatusFailed: case kPMJobStatusCanceled: { // 打印失败/取消提示 NSAlert *alert = [[NSAlert alloc] init]; alert.messageText = @"打印终止"; alert.informativeText = @"打印被取消或发生错误"; [alert addButtonWithTitle:@"确定"]; [alert runModal]; // 清理资源 PMSessionRemovePrintJobListener(session, printer, PrintJobStatusCallback, context); PMSessionRelease(session); break; } default: break; } }); }
关键注意事项
- 使用PrintCore API时,必须手动管理
PMSession、PMPrinter等对象的内存,避免泄漏 - 打印状态回调运行在后台线程,所有UI更新操作必须切换到主线程
- Swift项目需要先创建桥接文件引入PrintCore框架,并且调整回调函数的语法适配Swift
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

