在经过数周的挫折后,我总结出了一种在Swift应用程序中创建分页PDF的终极方法。它并不像看起来那么复杂(以下是基于Swift 2):
注意:在阅读更多内容之前,您应该知道我在Github上制作了一个简单的工具,让您可以在较少的步骤(以及Swift 3中,不需要任何Objective-C)中完成此操作。 请点击此处查看。
第1步:正确设置您的应用程序沙箱。每个提交的Mac应用程序都需要正确的应用程序沙箱,因此最好现在花30秒钟正确设置它。如果还没有打开,请转到Target设置,然后到Capabilities标题。在顶部启用应用程序沙箱。您应该看到许多子功能,启用您的应用程序需要的任何一个,并确保将User Selected File
设置为Read/Write
。
第2步:将此函数添加到您的代码中,它将创建一个不可见的Web视图并将您的文本添加到其中。
func createPDF(fromHTMLString: String) {
self.webView.mainFrame.loadHTMLString(htmlString, baseURL: nil)
self.delay(1) {
MyCreatePDFFile(self.webView)
}
}
第三步: 创建delay()
函数,让Xcode等待一秒钟以便HTML加载到Web视图中。
func delay(delay:Double, closure:()->()) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
}
(注:对于Swift 3版本的此函数,请前往此处。)
步骤4:在您在第2步添加的函数上方添加我们WebView的声明。
var webView = WebView()
第五步: 你可能会注意到我们还没有创建 MyCreatePDFFile()
函数。事实证明,在Swift中无法将此WebView转换为PDF,所以我们将不得不转向Objective-C (叹气)。是的,你必须在你的Swift应用程序中运行一些Objective-C代码。
第六步:通过转到 File
-> New
-> File
(或按下CMD + N)然后双击选择 Objective-C File
来创建一个 .m
文件。将其命名为 CreatePDF.m
并将其保留为空文件。
第七步:在添加您的 .m
文件时,您应该会收到提示添加桥接头文件:
![enter image description here](https://istack.dev59.com/nakLZ.webp)
点击 Yes
。
如果您没有看到提示,或者意外删除了您的桥接头文件,请添加一个新的 .h
文件到您的项目中,并将其命名为 <#YourProjectName#>-Bridging-Header.h
在某些情况下,特别是在使用ObjC框架时,您不会显式地添加Objective-C类,而Xcode无法找到链接器。在这种情况下,创建以上述方式命名的Bridging Header .h
文件,然后确保将其路径链接到您的目标项目设置中,如下所示:
![enter image description here](https://istack.dev59.com/8LiwF.gif)
第八步:通过转到 File
-> New
-> File
(或按下CMD + N)然后双击选择 Header File
来创建一个 .h
文件。将其命名为 CreatePDF.h
。
第九步:在您的 CreatePDF.h
文件中,添加以下代码,导入Cocoa和WebKit,并设置PDF创建函数:
#ifndef CreatePDF_h
#define CreatePDF_h
#import <Cocoa/Cocoa.h>
#import <WebKit/WebKit.h>
@interface Thing : NSObject
void MyCreatePDFFile(WebView *thewebview);
@end
#endif
步骤10:现在是设置用于创建PDF的.m
文件的时候了。首先将以下内容添加到空的.m
文件中:
#import "CreatePDF.h"
#import <Cocoa/Cocoa.h>
#import <WebKit/WebKit.h>
@implementation Thing
void MyCreatePDFFile(WebView *thewebview) {
}
@end
第11步:现在您可以将代码添加到MyCreatePDFFile(..)
函数中。这是函数本身(它放在当前空的void
函数内):
NSDictionary *printOpts = @{
NSPrintJobDisposition: NSPrintSaveJob // sets the print job to save the PDF instead of print it.
}
NSPrintInfo *printInfo = [[NSPrintInfo alloc] initWithDictionary:printOpts]
[printInfo setPaperSize:NSMakeSize(595.22, 841.85)]
[printInfo setTopMargin:10.0]
[printInfo setLeftMargin:10.0]
[printInfo setRightMargin:10.0]
[printInfo setBottomMargin:10.0]
NSPrintOperation *printOp = [NSPrintOperation printOperationWithView:[[[thewebview mainFrame] frameView] documentView] printInfo:printInfo]
printOp.showsPrintPanel = NO
printOp.showsProgressPanel = NO
[printOp runOperation]
第12步:现在将此添加到您的桥接头文件中,以使您的Swift文件能够查看您刚刚创建的Objective-C函数。
步骤 13: 这段代码不应该有任何错误,但如果还有,请在下面评论区留言。
步骤 14: 要在你的 Swift 文件中的任何位置调用 createPDF
函数,请按照以下步骤进行:
createPDF("<h1>Title!</h1><p>\(textview.text!)</p>")
在createPDF
内部看到的字符串是HTML,可以编辑成任何HTML格式。如果您不了解HTML,可以在这里查看一些基础知识 right here。
就这样! 您现在应该能够从Cocoa/Mac应用程序中直接创建分页PDF文件了。
鸣谢
注意:此答案已经测试可在Xcode 7、Swift 2和OS X El Captian上运行。如果您在使用Xcode 8/Swift 3/macOS Sierra时遇到任何问题,请告诉我。