How to load local html file into UIWebView - ios

I'm trying to load a html file into my UIWebView but it won't work. Here's the stage: I have a folder called html_files in my project. Then I created a webView in interface builder and assigned an outlet to it in the viewController. This is the code I'm using to append the html file:
-(void)viewDidLoad
{
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:#"sample" ofType:#"html" inDirectory:#"html_files"];
NSData *htmlData = [NSData dataWithContentsOfFile:htmlFile];
[webView loadData:htmlData MIMEType:#"text/html" textEncodingName:#"UTF-8" baseURL:[NSURL URLWithString:#""]];
[super viewDidLoad];
}
That won't work and the UIWebView is blank. I'd appreciate some help.

probably it is better to use NSString and load html document as follows:
Objective-C
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:#"sample" ofType:#"html"];
NSString* htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:nil];
[webView loadHTMLString:htmlString baseURL: [[NSBundle mainBundle] bundleURL]];
Swift
let htmlFile = NSBundle.mainBundle().pathForResource("fileName", ofType: "html")
let html = try? String(contentsOfFile: htmlFile!, encoding: NSUTF8StringEncoding)
webView.loadHTMLString(html!, baseURL: nil)
Swift 3 has few changes:
let htmlFile = Bundle.main.path(forResource: "intro", ofType: "html")
let html = try? String(contentsOfFile: htmlFile!, encoding: String.Encoding.utf8)
webView.loadHTMLString(html!, baseURL: nil)
Did you try?
Also check that the resource was found by pathForResource:ofType:inDirectory call.

EDIT 2016-05-27 - loadRequest exposes "a universal Cross-Site Scripting vulnerability." Make sure you own every single asset that you load. If you load a bad script, it can load anything it wants.
If you need relative links to work locally, use this:
NSURL *url = [[NSBundle mainBundle] URLForResource:#"my" withExtension:#"html"];
[webView loadRequest:[NSURLRequest requestWithURL:url]];
The bundle will search all subdirectories of the project to find my.html. (the directory structure gets flattened at build time)
If my.html has the tag <img src="some.png">, the webView will load some.png from your project.

by this you can load html file which is in your project Assets(bundle) to webView.
UIWebView *web = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
[web loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:#"test" ofType:#"html"]isDirectory:NO]]];
may be this is useful to you.

I guess you need to allocate and init your webview first::
- (void)viewDidLoad
{
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:#"sample" ofType:#"html" inDirectory:#"html_files"];
NSData *htmlData = [NSData dataWithContentsOfFile:htmlFile];
webView = [[UIWebView alloc] init];
[webView loadData:htmlData MIMEType:#"text/html" textEncodingName:#"UTF-8" baseURL:[NSURL URLWithString:#""]];
[super viewDidLoad];
}

A Simple Copy-Paste code snippet:
-(void)LoadLocalHtmlFile:(NSString *)fileName onWebVu:(UIWebView*)webVu
{
[webVu loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:fileName ofType:#"html"]isDirectory:NO]]];
}
Note:
Make sure the html file's Target membership is checked otherwise following exception will get thrown :-
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '*** -[NSURL initFileURLWithPath:isDirectory:]: nil string parameter'

For Swift 3 and Swift 4:
let htmlFile = Bundle.main.path(forResource: "name_resource", ofType: "html")
let html = try! String(contentsOfFile: htmlFile!, encoding: String.Encoding.utf8)
self.webView.loadHTMLString(html, baseURL: nil)

UIWebView *web=[[UIWebView alloc]initWithFrame:self.view.frame];
//[self.view addSubview:web];
NSString *filePath=[[NSBundle mainBundle]pathForResource:#"browser_demo" ofType:#"html" inDirectory:nil];
[web loadRequest:[NSURLRequest requestWhttp://stackoverflow.com/review/first-postsithURL:[NSURL fileURLWithPath:filePath]]];

May be your HTML file doesn't support UTF-8 encoding, because the same code is working for me.
Or u can also these line of code:
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:#"Notes For Apple" ofType:#"htm" inDirectory:nil];
NSString* htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:nil];
[WebView loadHTMLString:htmlString baseURL:nil];

Here the way the working of HTML file with Jquery.
_webview=[[UIWebView alloc]initWithFrame:CGRectMake(0, 0, 320, 568)];
[self.view addSubview:_webview];
NSString *filePath=[[NSBundle mainBundle]pathForResource:#"jquery" ofType:#"html" inDirectory:nil];
NSLog(#"%#",filePath);
NSString *htmlstring=[NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
[_webview loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:filePath]]];
or
[_webview loadHTMLString:htmlstring baseURL:nil];
You can use either the requests to call the HTML file in your UIWebview

Make sure "html_files" is a directory in your app's main bundle, and not just a group in Xcode.

A new way to do this using swift. The UIWebView is no more and WKWebView is the new class to load web pages, which ensures the Safari features to the web view.
import WebKit
let preferences = WKPreferences()
preferences.javaScriptCanOpenWindowsAutomatically = false
let configuration = WKWebViewConfiguration()
configuration.preferences = preferences
let webView = WKWebView(frame: self.view.bounds, configuration: configuration)
let request = NSURLRequest(URL: NSURL(string: "http://nshipster.com"))
webView.loadRequest(request)

Swift iOS:
// get server url from the plist directory
var htmlFile = NSBundle.mainBundle().pathForResource("animation_bg", ofType: "html")!
var htmlString = NSString(contentsOfFile: htmlFile, encoding: NSUTF8StringEncoding, error: nil)
self.webView.loadHTMLString(htmlString, baseURL: nil)

Here's Swift 3:
if let htmlFile = Bundle.main.path(forResource: "aa", ofType: "html"){
do{
let htmlString = try NSString(contentsOfFile: htmlFile, encoding:String.Encoding.utf8.rawValue )
messageWebView.loadHTMLString(htmlString as String, baseURL: nil)
}
catch _ {
}
}

[[NSBundle mainBundle] pathForResource:#"marqueeMusic" ofType:#"html"];
It may be late but if the file from pathForResource is nil you should add it in the Build Phases > Copy Bundle Resources.

if let htmlFile = NSBundle.mainBundle().pathForResource("aa", ofType: "html"){
do{
let htmlString = try NSString(contentsOfFile: htmlFile, encoding:NSUTF8StringEncoding )
webView.loadHTMLString(htmlString as String, baseURL: nil)
}
catch _ {
}
}

In Swift 2.0, #user478681's answer might look like this:
let HTMLDocumentPath = NSBundle.mainBundle().pathForResource("index", ofType: "html")
let HTMLString: NSString?
do {
HTMLString = try NSString(contentsOfFile: HTMLDocumentPath!, encoding: NSUTF8StringEncoding)
} catch {
HTMLString = nil
}
myWebView.loadHTMLString(HTMLString as! String, baseURL: nil)

Put all the files (html and resources)in a directory (for my "manual"). Next, drag and drop the directory to XCode, over "Supporting Files". You should check the options "Copy Items if needed" and "Create folder references". Next, write a simple code:
NSURL *url = [[NSBundle mainBundle] URLForResource:#"manual/index" withExtension:#"html"];
[myWebView loadRequest:[NSURLRequest requestWithURL:url]];
Attention to #"manual/index", manual is the name of my directory!!
It's all!!!! Sorry for my bad english...
=======================================================================
Hola desde Costa Rica. Ponga los archivos (html y demás recursos) en un directorio (en mi caso lo llamé manual), luego, arrastre y suelte en XCode, sobre "Supporting Files". Usted debe seleccionar las opciones "Copy Items if needed" y "Create folder references".
NSURL *url = [[NSBundle mainBundle] URLForResource:#"manual/index" withExtension:#"html"];
[myWebView loadRequest:[NSURLRequest requestWithURL:url]];
Presta atención a #"manual/index", manual es el nombre de mi directorio!!

When your project gets bigger, you might need some structure, so that your HTML page can reference files located in subfolders.
Assuming you drag your html_files folder to Xcode and select the Create folder references option, the following Swift code ensures that the WKWebView supports also the resulting folder structure:
import WebKit
#IBOutlet weak var webView: WKWebView!
if let path = Bundle.main.path(forResource: "sample", ofType: "html", inDirectory: "html_files") {
webView.load( URLRequest(url: URL(fileURLWithPath: path)) )
}
This means that if your sample.html file contains an <img src="subfolder/myimage.jpg"> tag, then the image file myimage.jpg in subfolder will also be loaded and displayed.
Credits: https://stackoverflow.com/a/8436281/4769344

Related

How to load the html file with pdf on iOS WKWebView

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);

WebView loadHTMLString:baseURL: not loading css

I have this this code:
NSURL *mainBundleURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
[webView loadHTMLString:htmlFile baseURL:mainBundleURL];
I know the htmlFile is correct. It has inside:
<link rel="stylesheet" type="text/css" href="stylesheet.css">
I also know the stylesheet.css in in the mainBundle. I checked the project.app contents.
Problem is that is the webview is empty. But if I use base Url as nil:
[webView loadHTMLString:htmlFile baseURL:nil];
The webview shows the content, but without the css file.
I have no idea why this is not working. Thanks in advance.
I solved this using the resourceURL property
NSURL *baseURL = [[NSBundle mainBundle] resourceURL];
and then [webView loadHTMLString:htmlFile baseURL:baseURL];
-Sal
Most examples reference baseUrl: nil but in order to access the CSS file you need to reference the bundle so that the <link rel="stylesheet" ... can access the file.
This is my solution in Swift 3:
let baseUrl : URL = Bundle.main.resourceURL! as URL
let htmlFile = Bundle.main.path(forResource: "*html file name*", ofType: "html")
let htmlString = try? String(contentsOfFile: htmlFile!, encoding: String.Encoding.utf8)
webView.loadHTMLString(htmlString!, baseURL: baseUrl)
Credit the Sal's answer for pointing this out.
Perhabs shouldStartLoadWithRequest method blocks your request. Try this:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
if ([request.URL.absoluteString hasPrefix:#"file"]) {return YES;}
//deal with the request
}

Load Image from UIwebview fail

I am using Webview to load a image file stored in my app Library Directory, first i tried use resourcePath, and bundle path
NSString * html = [[NSString alloc] initWithFormat:#"<img src=\"file://%#\"/>", filename];
[self.webView loadHTMLString:newhtml baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] resourcePath]]];
the problem is no matter what i set in the baseUrl, i can not load the image correctly , i also tried filePath:
[self.webView loadHTMLString:newhtml baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] filePath]]];
but if i set the absolute path of the image file in the html , all the things is ok, i wonder why?
Have a look at this post: Using HTML and Local Images Within UIWebView
The top answer clearly said that using file: paths to refer to images does not work with UIWebView.
All you need to do is to pass the basepath. Example:
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
[webView loadHTMLString:htmlString baseURL:baseURL];
Then just need to reference it like this: <img src="myimage.png">

UIWebView not loading local .html file

I a trying to view an .html file (index.html) that is stored in my Bundle (in my Supporting Files).
The .html file sits in a folder called HTML. My code is as follows:
- (void)viewDidLoad
{
[super viewDidLoad];
_viewWeb.delegate = self;
NSString *path = [[NSBundle mainBundle]
pathForResource:#"index" ofType:#"html" inDirectory:#"HTML"];
NSURL *url = [NSURL fileURLWithPath:path];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[_viewWeb setScalesPageToFit:YES];
[self.viewWeb loadRequest:request];
}
My header file looks as follows:
#interface D6ViewController : UIViewController <UIWebViewDelegate>
{
IBOutlet UIWebView *viewWeb;
}
#property (weak, nonatomic) IBOutlet UIWebView *viewWeb;
#end
I synthesized property as viewWeb = _viewWeb. The viewcontroller holding the UIWebView loads fine but shows a white screen with no webpage. I have set the outlets in the IB.
Any ideas? Thanks,
You are using a relative path (hence the blue color of a folder). You can actually find the answer to this problem here Load resources from relative path using local html in uiwebview or below:
Drag the resource into your xcode project, you will get two options "create groups for any added folders" and "create folders references for any added folders". Select the "create folder references.." option.
The code below should work.
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"index" ofType:#"html" inDirectory:#"/HTML"]];
[webView loadRequest:[NSURLRequest requestWithURL:url]];
try this
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"index" ofType:#"html"]isDirectory:NO]]];
In Swift:
func pathForResource(name: String?, ofType ext: String?, inDirectory subpath: String?) -> String?
- name: Name of Hmtl;
- ofType ext: extension for type of file. In this case "html";
- inDirectory subpath: the folder where are the file. In this case the file is in root folder;
let path = NSBundle.mainBundle().pathForResource("dados", ofType: "html", inDirectory: "root")
var requestURL = NSURL(string:path!);
var request = NSURLRequest(URL:requestURL);
webView.loadRequest(request)
You are wrong, here is the correct code:
var requestURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("index", ofType: "html", inDirectory: "www")!)
var request = NSURLRequest(URL:requestURL!)
myWebView.loadRequest(request)
You can use this If you are not saving your HTML file in any directory.If you are saving your HTML file in any directory then specify the directory name in "inDirectory" parameter.
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:#"privacy-Policy" ofType:#"html" inDirectory:nil];
NSData *htmlData = [NSData dataWithContentsOfFile:htmlFile];
[_webView loadData:htmlData MIMEType:#"text/html" textEncodingName:#"UTF-8" baseURL:[NSURL URLWithString:#""]];

iOS Load Image in UIWebView

Desperately trying to figue out how to load a local image (saved in local xcode bundle) into the following HTML through a UIWebView. I have spent countless hours following other guides but nothing seems to work, all throw erros. Am trying to add a local image in the following NSString where I have written IMAGEGOESHERE -
{
[super viewDidLoad];
self.title = _restaurant.title;
[[self navigationController] setNavigationBarHidden:NO animated:NO];
self.activityIndicatorView.hidden = NO;
[self.activityIndicatorView startAnimating];
[self loadImageInNewThread];
NSString *webViewContent = [NSString stringWithFormat:#"<html><head><style>* {font-family: Helvetica}</style></head><body><center>%# - %#<br><br><b>Restaurant:</b>%#</b><br>IMAGEGOESHERE<br></center></b></body></html>", _restaurant.openingTime,_restaurant.closingTime, _restaurant.name];
[self.webView loadHTMLString:webViewContent baseURL:nil];
}
I hope you can help as its driving me mad!
You need to reference first the path of your image:
NSString *pathImg = [[NSBundle mainBundle] pathForResource:#"yourimage" ofType:#"png"];
and then specify your path in your webViewContent along with the size of your image:
NSString* webViewContent = [NSString stringWithFormat:
#"<html>"
"<body>"
"<img src=\"file://%#\" width=\"200\" height=\"500\"/>"
"</body></html>", pathImg];
This code should work,
Just replace yourFile with the name of your PDF, and webView with the name of your webView.
Then Replace ofType to the extension of your image.
//PDF View
//Creating a path pointing to a file.pdf
NSString *path = [[NSBundle mainBundle] pathForResource:#"yourFile" ofType:#"pdf"];
//Creating a URL which points towards our path
NSURL *url = [NSURL fileURLWithPath:path];
//Creating a page request which will load our URL (Which points to our path)
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//Telling our webView to load our above request
[webView loadRequest:request];
NSString *pathImg = [[NSBundle mainBundle] pathForResource:#"yourimage" ofType:#"png"];
NSString* webViewContent = [NSString stringWithFormat:
#"<html>"
"<body>"
"<img src=\"file://%#\" width=\"200\" height=\"500\"/>"
[webView loadHTMLString:webViewContent baseURL:nil];
You must add the last line with a base url of nil

Resources