如何在iOS WKWebView上使用pdf加载html文件

时间:2016-08-11 09:13:08

标签: ios uiwebview wkwebview pdfjs

在我的项目中,我正在使用PDFJS库。我正在UIWebView上加载本地pdf。但这占用了大量的RAM内存,并且在某个时间点,它崩溃了。为避免这种情况,我想使用WKWebView

UIWebview中,我这样使用(self指的是UIView的子类)

UIWebView *uiWebview = [[UIWebView alloc] initWithFrame:self.frame];
[self addSubview:uiWebview];
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"swift_tutorial" ofType:@"pdf"];
NSString *sPath = [[NSBundle mainBundle] pathForResource:@"viewer" ofType:@"html" inDirectory:@"PDFJS/web"];
NSString *finalPath = [NSString stringWithFormat:@"%@?file=%@#page=1",sPath,filePath];
self.urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:finalPath]];
[uiWebview loadRequest:self.urlRequest];

当我在上面的代码段中打印finalPath时,控制台输出为/var/containers/Bundle/Application/DF419672-CF14-4B60-BE4F-EC0AC07C23AE/WebviewPOC.app/PDFJS/web/viewer.html?file=/var/containers/Bundle/Application/DF419672-CF14-4B60-BE4F-EC0AC07C23AE/WebviewPOC.app/swift_tutorial.pdf#page=1

WKWebView中,loadFileURLloadHTMLString方法可用于加载本地html文件或本地pdf文件,效果很好。但不是两个。对于这个html文件,如何附加本地pdf路径并加载WKWebView

任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:0)

让我回答我自己的问题。

我使用WKWebViewLocal库来创建localhost服务器。 现在,这将创建通过主机名访问本地文件。使用这种方法应用'内存利用率已经过很多优化(仅限于WKWebView)。

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"swift_tutorial" ofType:@"pdf"];    
NSString *htmlPath = [[NSBundle mainBundle] pathForResource:@"viewer" ofType:@"html" inDirectory:@"PDFJS/web"];
NSString *finalPath = [NSString stringWithFormat:@"http://localhost:8080%@?file=%@#page=1",htmlPath, filePath];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:finalPath]];
[self.webView loadRequest:request];

现在,最终路径将是

http://localhost:8080/~~~~~~~/PDFJS/web/viewer.html?file=/Users/~~~~~~/swift_tutorial.pdf#page=1

答案 1 :(得分:0)

因为Apple会拒绝使用UIWebView API的应用程序,所以在从UIWebView移到WKWebView的过程中,我遇到了同样的问题。但是由于我使用Xamarin框架,所以无法使用WKWebViewLocal库。我的解决方案非常相似。

首先,您需要在CustomRenderer for WKWebView的OnElementChanged方法中添加以下代码:

Control.Configuration.Preferences.SetValueForKey(NSObject.FromObject(true), new NSString("allowFileAccessFromFileURLs"));

它将完全访问此控件的文件。没有它,pdfjs将无法加载文档,并且始终显示为空。

然后,您需要更改用于读取文件的代码:

_pdfViewerAddress = (NSString)NSBundle.PathForResourceAbsolute("pdfjs/web/viewer", "html", NSBundle.MainBundle.ResourcePath);

if (UsePDFJS)
                {
                    var pdfjsUrlString = $"file://{_pdfViewerAddress}";
                    var pdfjsUrl = new NSUrl(pdfjsUrlString);

                    var docUrlString = $"file://{GetDocumentUrl()}";
                    var docFolderUrlString = new NSUrl($"file://{Element.PathWithoutFileName}");

                    var finalUrl = new NSUrl($"{pdfjsUrl}?file={docUrlString}#page=1");

                    Control.LoadFileUrl(finalUrl, docFolderUrlString);
                }
                else
                {
                    var error = new NSError();
                    var documentDirUrl = NSFileManager.DefaultManager.GetUrl(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomain.User, null, false, out error);
                    var dotsFolderUrl = documentDirUrl.Append("..", true);
                    var libFolderUrl = dotsFolderUrl.Append("Library", true);
                    var tempFolderUrl = libFolderUrl.Append("TemporaryFiles", true);
                    var fileUrl = new NSUrl($"file://{GetDocumentUrl()}");

                    Control.LoadFileUrl(fileUrl, tempFolderUrl);
                }

在使用pdfjs的情况下,finalUrl应该如下所示:

file:///private/var/containers/Bundle/Application/80424409-E164-4409-A72B-43B32EC51F1A/iOS.app/pdfjs/web/viewer.html?file=file:///var/mobile/Containers/Data/Application/ED7233AE-8D10-41DC-8AF4-10662F14A883/Documents/../Library/TemporaryFiles/10850908.pdf#page=1

仅此而已。无需外部库。如果要从BundleResources打开文档,这也可以使用。您可以使用以下代码轻松访问它:

(NSString)NSBundle.PathForResourceAbsolute("Guide", "pdf", NSBundle.MainBundle.ResourcePath);