[英]How to load the html file with pdf on iOS WKWebView
In my project, I am using PDFJS
library.在我的项目中,我使用的是PDFJS
库。 I am loading a local pdf on UIWebView
.我正在UIWebView
上加载本地 pdf。 But this occupies lot of RAM memory and at a point of time, its crashing.但这会占用大量 RAM 内存,并且在某个时间点会崩溃。 To avoid this, I want to use WKWebView
.为了避免这种情况,我想使用WKWebView
。
In UIWebview
, I am using like this ( self
refers to subclass of UIView
)在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];
When I print finalPath in the above snippet, the console output is /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
当我在上面的代码片段中打印 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
In WKWebView
, loadFileURL
, loadHTMLString
methods can be used to load local html file or a local pdf file, which works fine.在WKWebView
, loadFileURL
, loadHTMLString
方法可用于加载本地 html 文件或本地 pdf 文件,工作正常。 But not both.但不能两者兼而有之。 For this html file, how to append the local pdf path and load in the WKWebView
?对于这个 html 文件,如何附加本地 pdf 路径并加载到WKWebView
?
Any help appreciated.任何帮助表示赞赏。
Let me answer my own question.让我回答我自己的问题。
I have used WKWebViewLocal library for creating a localhost server.我使用WKWebViewLocal库来创建本地主机服务器。 Now, this will create access the local files via host name.现在,这将通过主机名创建对本地文件的访问。 Using this approach apps' memory utilization has been optimized a lot (Only because of WKWebView).使用这种方法应用程序的内存利用率已经优化了很多(仅因为 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];
now, the finalpath will be现在,最终路径将是
http://localhost:8080/~~~~~~~/PDFJS/web/viewer.html?file=/Users/~~~~~~/swift_tutorial.pdf#page=1
Because Apple will reject apps that use UIWebView API I had the same problem during moving from UIWebView to WKWebView.因为 Apple 会拒绝使用 UIWebView API 的应用程序,所以我在从 UIWebView 移动到 WKWebView 时遇到了同样的问题。 But since i'm using Xamarin framework i can't use WKWebViewLocal library.但由于我使用的是 Xamarin 框架,因此无法使用 WKWebViewLocal 库。 My solution is very similar.我的解决方案非常相似。
First of all you need to add this code in OnElementChanged method in your CustomRenderer for WKWebView:首先,您需要在 WKWebView 的 CustomRenderer 中的 OnElementChanged 方法中添加此代码:
Control.Configuration.Preferences.SetValueForKey(NSObject.FromObject(true), new NSString("allowFileAccessFromFileURLs"));
It will grand access to files for this Control.它将访问此控件的文件。 Without it pdfjs won't be able to load documents and will always appear empty.没有它 pdfjs 将无法加载文档并且总是显示为空。
Then you need to change the code for reading files:然后需要修改读取文件的代码:
_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);
}
In case of use pdfjs finalUrl should look like this:如果使用 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
That's all.仅此而已。 No external library needed.不需要外部库。 This also works if you want to open document from BundleResources.如果您想从 BundleResources 打开文档,这也适用。 You can easily access it with this code:您可以使用以下代码轻松访问它:
(NSString)NSBundle.PathForResourceAbsolute("Guide", "pdf", NSBundle.MainBundle.ResourcePath);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.