In my project, I am using PDFJS library. I am loading a local pdf on UIWebView. But this occupies lot of RAM memory and at a point of time, its crashing. To avoid this, I want to use WKWebView.
In UIWebview, I am using like this (self refers to subclass of 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
In WKWebView, loadFileURL, loadHTMLString methods can be used to load local html file or a local pdf file, which works fine. But not both. For this html file, how to append the local pdf path and load in the WKWebView ?
Any help appreciated.
Let me answer my own question.
I have used WKWebViewLocal library for creating a localhost server.
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).
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. But since i'm using Xamarin framework i can't use WKWebViewLocal library. My solution is very similar.
First of all you need to add this code in OnElementChanged method in your CustomRenderer for WKWebView:
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.
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:
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. You can easily access it with this code:
(NSString)NSBundle.PathForResourceAbsolute("Guide", "pdf", NSBundle.MainBundle.ResourcePath);
Related
It's a weird problem, there are many different type files on my list such as pdf, ppt, xls etc, everything works fine with them but some doc files are not displaying.
I use WebView, UIDocumentInteractionController, QLPreviewController to display the files but I have the same problem. Like this
When I use webview I have this screen
The files size are OK, i mean not too big and there is no problem while opening in computer. I tested the app in a real device, same problem..
Here is the similar problem and i think that there is a bug in ios as they said
How to manage memory within a QLPreviewController
But I believe that there should be a solution, is it a memory problem? I use Xamarin.iOS and this is my code
QLPreviewItemBundle prevItem = new QLPreviewItemBundle(info.FileName, info.FilePath);
QLPreviewController previewController = new QLPreviewController();
previewController.DataSource = new PreviewControllerDS(prevItem);
NavigationController.PushViewController(previewController, true);
and this is for UIDocumentInteractionController
var documentPath = docInfo.FilePath;
UIDocumentInteractionController interationController = UIDocumentInteractionController.FromUrl(NSUrl.FromFilename(documentPath));
interationController.Name = docInfo.FileName;
interationController.ViewControllerForPreview = (controller) => NavigationController;
interationController.DidEndPreview += (sender, e) =>
{
interationController.Dispose(); interationController = null;
};
InvokeOnMainThread(() => interationController.PresentPreview(true));
Try using this method,
-(void)loadDocument:(NSString*)documentName inView:(UIWebView*)webView
{
NSString *path = [[NSBundle mainBundle] pathForResource:documentName ofType:nil];
NSURL *url = [NSURL fileURLWithPath:path];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
}
// Calling -loadDocument:inView:
[self loadDocument:#"mydocument.rtfd.zip" inView:self.myWebview];
This is what I'm trying to do:
Get a .pdf from external URL
Save it into my local disk
Display it in a WebView
Allow the user to move the .pdf to another app who can read .pdf
Everything from 1 to 3 works fine. But nothing is moved/shared to/with other apps. I can't understand what I'm doing wrong. This is what I'm doing.
How I save the pdf in the Documents folder (viewDidLoad):
// to save the pdf into local file system (tempString is the pdf url)
NSData *pdfData = [[NSData alloc]
initWithContentsOfURL:[NSURL URLWithString:tempString]];
NSString *resourceToPath = [[NSString alloc]
initWithString:[[[[NSBundle mainBundle] resourcePath]
stringByDeletingLastPathComponent]
stringByAppendingPathComponent:#"Documents"]];
NSString *filePAth = [resourceToPath stringByAppendingPathComponent:#"myPDF.pdf"];
[pdfData writeToFile:filePAth atomically:YES];
// to populate the WebView
NSURL *url2 = [NSURL fileURLWithPath:filePAth];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url2];
[my_web_view setUserInteractionEnabled:YES];
//[editoriale_view setDelegate:self];
[my_web_view loadRequest:requestObj];
In my viewDidLoad() function I create a button to allow the user to open a list of apps who can read .pdf files:
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemBookmarks target:self
action:#selector(show_Button)];
And here's my show_Button function:
-(void)show_Button {
NSString *resourceToPath = [[NSString alloc]
initWithString:[[[[NSBundle mainBundle] resourcePath]
stringByDeletingLastPathComponent]
stringByAppendingPathComponent:#"Documents"]];
NSString *filePAth = [resourceToPath
stringByAppendingPathComponent:#"myPDF.pdf"];
NSLog(#"filePath = %#", filePAth);
NSURL *url2 = [NSURL fileURLWithPath:filePAth];
NSLog(#"url2 = %#", url2);
UIDocumentInteractionController *docContr = [UIDocumentInteractionController
interactionControllerWithURL:url2];
[docContr presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES];
}
When I try this on my device everything works fine until I tap on one of the icons in the list (i.e. the iBooks one). Then the app closes (it doesn't crash, it simply closes).
Here's what the console prints for the two logs I put in the show_Button function:
1. filePath = /Users/[MY_USER]/Library/Application Support/iPhone
Simulator/6.1/Applications/[MY_EXAD_APP_ID]/Documents/myPDF.pdf
2. url2 = file://localhost/Users/[MY_USER]/Library/Application%20Support/
iPhone%20Simulator/6.1/Applications/[MY_EXAD_APP_ID]/Documents/myPDF.pdf
Anyone wants to try to make me understand what I'm doing wrong? I'm using Xcode 4.6. I browsed my iPhone app file system with a third-party software and the file "MyPDF.pdf" actually IS in the Documents" folder, and that's clear because the WebView is correctly populated.
Change CGRectZero to self.view.bounds when you display the document controller.
Solved. I had not implemented the UIDocumentenInteractionController delegate in the .h file. Now I have and everything works fine. Thank you to #trojanfoe for the useful hint.
I have an image that I have in my bundle resources that I need to reference as a source file (src="") in my webView stringByEvaluatingJavaScriptFromString. I can reference external images from websites, but I do not know how to write the URL of the local image.
How could this be done?
An example to show how you could do this...
in my viewDidLoad, I am adding some example HTML into a UIWebView as shown below: (This could easily be a loadRequest: call to a remote URL)
NSString *html = #"<html><body><img id='theImage'></img></body></html>";
[self.webView loadHTMLString:html baseURL:nil];
You need to set the view controller as the delegate for the UIWebView, and wait until it has finished loading the HTML. You can then execute a script to amend the image URL:
- (void)webViewDidFinishLoad:(UIWebView *)webView {
// Get the path to the image in the bundle you wish to display, and create a URL from this path.
NSString *imagePath = [[NSString alloc] initWithString:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"MyImage.png"]];
NSURL *imageURL = [NSURL fileURLWithPath:imagePath];
// Create a script to execute in the web view.
NSString *script = [[NSString alloc] initWithFormat:#"document.getElementById('theImage').src = \"%#\";", imageURL];
// Execute the script.
[self.webView stringByEvaluatingJavaScriptFromString:script];
// Tidy up.
[imagePath release];
}
I've a problem that i couldn't solve, i wanna run the Apple - HTML5 Showcase - Gallary
in UIWebView inside my ipad app.
I've tried a local html file:
NSString *strr = [[NSBundle mainBundle] pathForResource:#"photo-gallery" ofType:#"html"];
NSString *str = [[NSString alloc] initWithContentsOfFile:strr encoding:NSASCIIStringEncoding error:nil];
NSLog(#"%#",str);
[webView loadHTMLString:str baseURL:nil];
and also a server html file, but it didn't work, can anyone help me, i wanna show an html5/css3 in UIWebView.
thx in advance.
hi this is what you can do
UIWebView *aWebView = [[UIWebView alloc] initWithFrame:webFrame];
//getthe path of the local html file
NSURL *baseURL = [NSURL fileURLWithPath:fileNamePath];
NSURLRequest *aRequest = [NSURLRequest requestWithURL:baseURL];
//load the html file into the web view.
[aWebView loadRequest:aRequest];
//add the web view to the content view
[view addSubview:aWebView];
For server html you simply skip the second line, and put the address.
Hope it helps
You can take a look at phonegap. Its a complete framework for building html5 apps inside a UIWebview with native capabilities.
See: http://www.phonegap.com
Since OS 3.0 UIWebView supports RTF files.
If you have a .rtf file, it's easy enough to load it into a uiwebview, e.g.
NSString *path = [[NSBundle mainBundle] pathForResource:documentName ofType:nil];
NSURL *url = [NSURL fileURLWithPath:path];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
When loading HTML stored in a string variable, you can use loadHTMLString.
How would one load RTF stored in a string directly into a UIWebView? For example, if you have a string containing {\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}....., using loadHTMLString will render it literally.
I would like to be able to render RTF from a string variable without having first to save it to a file.
Try loadData:MIMEType:textEncodingName:baseURL:. Haven't tried it, but it's worth a shot.