local html in UIWebView with images from Assets catalog - html

I'm trying to write code that loads a local html string into a UIWebView with images from the Assets.xcassets catalog.
Currently, I load the images from the main bundle, like this:
NSString *htmlString = [NSString stringWithFormat:#"<h1>My title</h1><img src='%#'/>", #"myImage1.png"];
[self.webView loadHTMLString:htmlString baseURL:[[NSBundle mainBundle] bundleURL]];
However, this is very limiting in respect to using different retina versions of the images (#2 and #3).
I would like to load the images instead from the asset catalog, but can't figure out how to do it.
Provided the image name in the html string, how do I load the image from the assests into the webView, while supporting #2 and #3 retina versions?

Here Is Given Code Try it..
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
[webView loadHTMLString:htmlString baseURL:baseURL];
==> like thi some images :
=================================================================
This is how to load/use a local html with relative references.
Use the below given code.
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:#"index" ofType:#"html" inDirectory:#"www"]];
[webview loadRequest:[NSURLRequest requestWithURL:url]];
Now all your relative links(like img/.gif, js/.js) in the html should get resolved.

Related

How to load localized html file from WKWebView?

1st StackOverflow question for me...
!! Objective-C !!
I'm in the process of updating an old app and am working on help screens.
I chose to display some useful How-tos through some html mainly for the ease of formatting the text (bullet points, colors, bold, underline etc...).
Since the app is a bit complex, The help screens are in a total of 3:
A main info webpage that links to 2 other detailed pages.
Tha app is localized in English (Base) and French.
Once the setup was complete, and with everything working fine, I went ahead and localized the base html files.
Now, they are neatly placed in the Base.lproj and fr.lproj files.
But when when I tap on a link to another page from the main WebView, nothing happens !
Any ideas ?
Thanks
Here are some bits of code I'm using:
In the .h file :
#interface howToViewController : UIViewController <WKUIDelegate>
{
WKWebView *infoText;
NSString *uRLString;
}
#property (nonatomic, retain) WKWebView *infoText;
In the .m file: (had to programmatically create the WKWebView because of the known Xcode 9 bug when creating it through Storyboards)
- (void)viewDidLoad
{
[super viewDidLoad];
WKWebViewConfiguration *theConfiguration = [[WKWebViewConfiguration alloc] init];
WKWebView *aWebView = [[WKWebView alloc] initWithFrame:self.view.frame
configuration:theConfiguration];
aWebView.UIDelegate = self;
self.infoText = aWebView;
NSURL *url = [[NSBundle mainBundle] URLForResource:#"infoHTML" withExtension:#"html"];
NSString *html = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
NSURL *baseUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
[infoText loadHTMLString:html baseURL:baseUrl];
[self.view addSubview:infoText];
}
In the html file, the links that no longer work once the files are localized:
<p>3/ More information is available for the respective tabs by pressing the following links :</p>
<ul><li>Limitations
</li></ul>
<ul><li>Fueling
</li></ul>
Working code from one of my apps. I'm using NSURLRequest and WKWebView's loadRequest instance method. I'm not sure what's going wrong with your use of loadHTMLString:baseURL: but I think it may have something to do with the value you're passing for the baseURL argument. Have you cleared the console, then single-stepped over that line of code to see if you're getting any message in the console?
NSURL *url = [[NSBundle mainBundle] URLForResource: pageString withExtension: #"html"];
NSURLRequest *request = [NSURLRequest requestWithURL: url];
[webView loadRequest: request];

Load html file from a framework is this possible?

Hi I want to load html and .js file from my project. These are the below steps i am following to load html file through framework but i am not able to hit html files.
Steps followed.
Created a framework which has webview as subview in it.
Created Resource.bundle and added all my html,.js files and images in the bundle.
When i add this framework into my project and try to access the image from the bundle i am not able to.
when i try to hit the html file i am not able to laod the html file in my webview.
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:#"Resource" ofType:#"bundle"];
NSString *htmlFile = [[NSBundle bundleWithPath:bundlePath] pathForResource:#"simple" ofType:#"html"];
NSString* htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:nil];
NSURL *url=[[NSBundle mainBundle] bundleURL];
[webview loadHTMLString:htmlString baseURL:url];
[self addSubview:webview];
Can anyone tell me why this wont work and is this the right approach to follow?
I create a bundle with index.html that call a js with a simple alert, with this code i'm able to se the alert
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:#"BundleName" ofType:#"bundle"];
NSString *htmlFile = [[NSBundle bundleWithPath:bundlePath] pathForResource:#"index" ofType:#"html"];
NSString* htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:nil];
[_web loadHTMLString:htmlString baseURL:[[NSBundle mainBundle] bundleURL]];
the html work in local? the webview is initialized?

How to show an image saved on Documents Directory inside local HTML? iOS

I've this app which needs to store images shown in a webview locally, and show those stored images again inside the same webview.
This what I've gotten so far...
// After download button clicked... Store image from URL locally
NSURL *url = [NSURL URLWithString:myURL];
NSData *urlData = [NSData dataWithContentsOfURL:url];
if ( urlData )
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory,#"filename.png"];
[urlData writeToFile:filePath atomically:YES];
}
// Get image path from Documents Directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"filename.png"];
// Display local html page
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"revistasPhotoswipe" ofType:#"html" inDirectory:#"www"]];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[_webView loadRequest:requestObj];
And in html file there's just a tag to show the image
<html>
<head></head>
<body><img src='filename.png' /></body>
</html>
Which is the right way to communicate the Documents Dir, with App Bundle and the HTML files to make this work? Another approach?
You can't use <body><img src='filename.png' /></body> because it references an object on a localserver that doesn't exist. You have a couple of options:
1. Javascript
A milliseconds after the page has loaded you should tell your webview to evaluate a javascript function.document["pictureIdFromProgam"].src = searchPic.src; as well as declaring your image element with <img src='throw.imgNotSet' id='pictureIdFromProgam'/>
2. String Manipulatoin
Another (less desirable, but quicker) option is to have your HTML file coded into an NSString and inserting the img link by using either replacing or %#s
Insertion:
[NSString stringWithFormat:#"<html><blah blah blah/><img src=%#/>",imagePathAsString];
and then you will be able to tell your webview to load the nsstring which contains the updated web content.

load a local css file into a webview

I built a simple ios app that loads a html downloaded from a server into a webview.
[self.webView loadHTMLString:notif.html baseURL:nil];
This works perfect. The problem is that i nedd to apply a local css file to the webview and I dont know how to do it.
I tried doing it this way, but the styles are not being applied.
NSString *HTML_HEADER=#"<HTML><HEAD><link rel='stylesheet' href='style.css' type='text/css'></HEAD><BODY>";
NSString *HTML_FOOTER=#"</BODY></HTML>";
NSString *htmlString = [NSString stringWithFormat:#"%#%#%#",HTML_HEADER,notif.html,HTML_FOOTER];
NSLog(#"htmlString %#", htmlString);
[self.webView loadHTMLString:htmlString baseURL:nil];
Any idea?
Thanks
UPDATE:
I tried to do the following:
NSString *HTML_HEADER=#"<HTML><HEAD><link rel='stylesheet' href='#FILE1#' type='text/css'></HEAD><BODY>";
NSString *HTML_FOOTER=#"</BODY></HTML>";
NSString *cssFilePath = [[NSBundle mainBundle] pathForResource:#"style" ofType:#"css"];
NSString *html_header_with_files = [HTML_HEADER stringByReplacingOccurrencesOfString:#"#FILE1#" withString:cssFilePath];
NSString *htmlString = [NSString stringWithFormat:#"%#%#%#",html_header_with_files,notif.html,HTML_FOOTER];
NSLog(#"htmlString %#", htmlString);
[self.webView loadHTMLString:htmlString baseURL:nil];
And in Build Phases i have added the style.css
UPDATE 2:
I also check if the style.css exists with
NSString* filePath = [[NSBundle mainBundle] pathForResource:#"style" ofType:#"css"];
NSLog(#"\n\nthe string %#",filePath);
The reason is CSS and JS files not available at runtime for render in HTML.
You need to take care of some points:
All CSS/JS/HTML files must be added to Project Properties >> Build Phases >> Copy Bundle Resources.
Check that all files are added if not then manually add those files.
All files are should be placed in the same folder, so that reference file path will be available at run time.
Instead of using directly file names, I will prefer you to use marker. Use symbols as a marker to replace with actual path of CSS and JS files.
For example:
NSString *HTML_HEADER=#"<HTML><HEAD><link rel='stylesheet' href='#FILE1#' type='text/css'></HEAD><BODY>";
NSString *HTML_FOOTER=#"</BODY></HTML>";
NSString *cssFilePath = [[NSBundle mainBundle] pathForResource:#"style" ofType:#"css"];
NSString *html_header_with_files = [HTML_HEADER stringByReplacingOccurrencesOfString:#"#FILE1#" withString:cssFilePath];
NSString *htmlString = [NSString stringWithFormat:#"%#%#%#",html_header_with_files,notif.html,HTML_FOOTER];
NSLog(#"htmlString %#", htmlString);
[self.webView loadHTMLString:htmlString baseURL:nil];
In above example I have replace style.css string from html part and add marker #FILE1#.
This marker is relative url to file style.css and it will be replace before html load in webView.
So whenever you would like to load html to webView, load all resource files from their relatives urls.
Here HTML_HEADER will be replace with actual path for all resources files.
You can import files (as CSS, JS ...) even without putting them into "Copy bundle resources", so you can just download CSS and use it during run of your app.
Trick is in setting "baseURL" parameter, which becomes root directory for your UIWebView.
// HTML file
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:htmlFileName ofType:#"html"];
NSString* htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:nil];
// root directory
NSURL *rootDir = [[NSBundle mainBundle] bundleURL];
[self.webView loadHTMLString:htmlString baseURL:rootDir];
Then, when you say
<link rel="stylesheet" type="text/css" href="style.css">
in your HTML file, app will look for style.css in rootDir directory (in this case, [[NSBundle mainBundle] bundleURL] )
I finally find the solution.
NSString *HTML_HEADER=#"<HTML><HEAD><link rel='stylesheet' href='#FILE1#' type='text/css'></HEAD><BODY>";
NSString *HTML_FOOTER=#"</BODY></HTML>";
NSString *cssFilePath = [[NSBundle mainBundle] pathForResource:#"style" ofType:#"css"];
NSString *html_header_with_files = [HTML_HEADER stringByReplacingOccurrencesOfString:#"#FILE1#" withString:cssFilePath];
NSString *htmlString = [NSString stringWithFormat:#"%#%#%#",html_header_with_files,notif.html,HTML_FOOTER];
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
NSLog(#"htmlString %#", htmlString);
[self.webView loadHTMLString:htmlString baseURL:baseURL];
Its necessary to specify the bundlePath in loadHTMLString:
The solution is a combination of the two answers given by #Kampai and #itzprintz

How to read image file at documents directory from ios webview

I am downloading image file and write to documents directory like below:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *objURL = #"http://test.test.com/file/image.png";
NSURL *objurl = [NSURL URLWithString:objURL];
NSData *imgData = [NSData dataWithContentsOfURL:objurl];
NSString *imgFile = [NSString stringWithFormat:#"%#/%#", documentsDirectory,#"image.png"];
[imgData writeToFile:imgFile atomically:YES];
In my webView, I loaded a html file from my bundle resource to use in my webView, but how do I have the tag in html to read the image.png in documents directory?
<html>
<body>
<img src="../what/is/the/path/to/use/image.png" />
</body>
</html>
You could give the URL for this image using an absolute path with a file:// scheme:
NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES)[0];
NSString *filePath = [NSString stringWithFormat:#"file://%#/image.png", documentsDirectory];
You could then run some javascript to update the src tag to update it to the new path:
NSString *javascript = [NSString stringWithFormat:#"var imageElement = document.getElementById('localFile'); imageElement.setAttribute('src', '%#');", filePath];
[self.webView stringByEvaluatingJavaScriptFromString:javascript];
In your HTML the path would look like something like:
<html>
<body>
<img id="localFile" src="file:///var/mobile/Applications/3D7D43E8-FA5E-4B19-B74C-669F7D1F3093/Documents/image.png" />
</body>
</html>
Instead of evaluating JavaScript, I just write down a placeholder in my html content, and replace it directly w/ the content needed:
NSString *htmlFilePath = [[NSBundle mainBundle] pathForResource:#"sample" ofType:#"html"];
NSString *htmlString = [NSString stringWithContentsOfFile:htmlFilePath encoding:NSUTF8StringEncoding error:&error];
if (error) {
// handle error
return;
}
NSString *imageFilePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:#"sample_image.png"];
NSURL *imageFileURL = [NSURL fileURLWithPath:imageFilePath];
NSString *sampleImageReplacement =
[NSString stringWithFormat:#"<img src=\"%#\" />", [imageFileURL absoluteString]];
// Replace the placeholder w/ real content,
// and of course, we can also replace it w/ empty string
// if the image cannot be found.
htmlString = [htmlString stringByReplacingOccurrencesOfString:#"%sample_image%"
withString:sampleImageReplacement];
...
[webView loadHTMLString:htmlString baseURL:nil];
You can load the images from the app bundle but you can not load the images from the documents directory directly.
But there is a work around.
Use CocoaHTTPServer to create a InAppHttpServer and you can access the images in documents directory using http URL in web view.
or else
Convert the image into base64 and load the image using evaluatejavascript of webview
document.getElementById('img').setAttribute( 'src', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==' );
You can not bind image source from beginning. You will have to do it via JavaScript.
You need to pass the path of the image to UIWebView by evaluating JS. Here you can pass the path of your image and JS will load the image into respective HTML tag.