I have a number of web pages that are used inside a UIWebView that currently reference resources with both relative and absolute paths like so:
<link rel="stylesheet" type="text/css" href="/css/path/mycss.css"/>
<img src="myimage.png" />
The HTML file itself is at path "/page/path/page.html" with myimage.png in the same directory. These same pages are also used for rendering directly in a browser and ideally I'd rather not change the paths. On the iPad, the web site content is dynamically loaded into the Documents directory for offline viewing. The problem is that there doesn't seem to be any way to get UIWebView to handle the resolution of the absolute paths. I'm using the following to load the content:
NSData *data = [NSData dataWithContentsOfFile:fullPath];
[self loadData:data MIMEType:#"text/html" textEncodingName:#"utf-8" baseURL:baseURL];
If I point baseURL at the "/page/path" directory, UIWebView will correctly find myimage.png, but will not find mycss.css. I also tried pointing baseURL at the Documents directory, but this fails to resolve either resource. In fact, I haven't been able to get UIWebView to resolve any absolute paths at all.
Has anyone been able to get absolute paths to work with UIWebView?
Did you try to use something like that (see below) for the path of your CSS ?
<link rel="stylesheet" type="text/css" href="../../css/path/mycss.css"/>
<img src="myimage.png" />
Why do you want some absolute path references in your html files ?
I don't think it is a good idea, because you cannot know your future users application installation pathes.
For example, my embedded web page is at
file://localhost/var/mobile/Applications/0E8A7BA5-8DB7-4F88-AC69-0E48F9182DD2/MyApp.app/homepage/index.html
The 0E8A7BA5-8DB7-4F88-AC69-0E48F9182DD2 part changes every time you delete your app !
I think the good way is
adding your website in xCode by selecting "Create folder references for any added folders"
only have some relative pathes
use :
NSString * urlString = [[NSBundle mainBundle] pathForResource:#"index" ofType:#"html" inDirectory:#"homepage"];
NSURL * url = [NSURL fileURLWithPath:urlString isDirectory:NO];
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:(NSTimeInterval)10.0 ];
Related
is it possible to load local content in a WebView when settings the BaseURL to something external?
I need to set the baseURL so something external because I'm integrating the Facebook Widget, what uses the same origin as the source file (origin=file).
So I've to set the origin to http://
But then I'm unable to load local ressources (like css, images), also when setting the absolute css file path in the bundle.
How can I fix that?
As far as I know you need set http or local and for the facebook use the native api.
https://developers.facebook.com/docs/ios
So you can do all in local with facebook api.
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:#"sample" ofType:#"html"];
NSString* htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:nil];
[webView loadHTMLString:htmlString baseURL:nil];
hope this helps
In my app,I download an HTML app and save it in documents directory.I open it using a UIwebview. This works fine. But the problem is,if I make any css change on my server and then download the app again,the changes are reflected in documents directory but when I open the app in UIwebview , the changes are not reflected there. If I open the .html file in safari , the css changes work.
I load my html file using the following code:
appReq = [NSURLRequest requestWithURL:appURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:20.0];
[self.webView loadRequest:appReq];
where appURL = [NSURL fileURLWithPath:"path to downloaded html app in documents directory"];
I tried to clear the caches using following methods:
[[NSURLCache sharedURLCache] removeCachedResponseForRequest:appReq];
and
[[NSURLCache sharedURLCache] removeAllCachedResponses];
but they do not help.
P.S : The changes are only reflected if I reopen my application.
Does anyone has any clue how to solve this?
You should generate a rendom number and append it to your path (to ignore the cache).
Instead of:
appURL = [NSURL fileURLWithPath:"path to downloaded html app in documents directory"];
use:
int randomNumber = rand() % 1012074;
appURL = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#&ignoreCache=%d",<path to downloaded html app in documents directory>,(int)randomNumber]];
I hope it will help you!
Good luck!
I want to load a web site on a UIWebView which is not under my control and edit/add certain UI changes (Some texts, images, etc) to it. Can I do this within my iOS source code? I can't change the hosted html contents since them not under my control.
If this cannot doable within iOS source code, please advice me the correct way to achieve this.
Load the webpage into an NSString, make any modifications and then put the html into the UIWebView.
NSURL *url = [NSURL URLWithString:#"http://example.com/"];
NSString *page = [NSString stringWithContentsOfURL:url usedEncoding:nil error:nil];
/* Make changes to page here */
[self.webView loadHTMLString:page baseURL:nil];
I'd get the dom with JavaScript, manipulate, then inject back with JavaScript.
See stringByEvaluatingJavaScriptFromString:.
You can write your own full featured, minified JavaScript, then pass into using this method.
// Change body color of any HTML content inside a UIWebView.
NSString *javaScript = #"document.getElementByTagName('body').backgroundColor = '#888';";
[webView stringByEvaluatingJavaScriptFromString:javaScript];
I have a few images that are part of a web page which i want to load into a webview. The images are saved locally.
I load the html like this, and everything works well:
NSURL *baseUrl = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
[self.webView loadHTMLString:myHtmlStringWithImgTags baseURL:baseUrl];
The html is displayed correctly.
When my IMG-tags look like this, everything works well:
<img src="image.png" />
However, I will get these images from html generated by EpiServer, and the img tags will look like this:
<img src="/image.png" />
I do not want to start parsing the html and remove the absolute path to root at the beginning of the src-tag. How to solve this? What should I have as baseUrl?
Thanks.
EDIT:
Seems to be a common problem:
Remap UIWebView root URL to [[NSBundle mainBundle] bundleURL]
Anyone got a solution except starting to hack the html and remove the root-paths?
I use a UIWebView to load a local html, and there is a PNG file inside the html created by Objc.
After the PNG file has been modified, I reload the html in UIWebView, but the image doesn't change. However, if I quit the app and reopen it, the image file will be changed to the new one.
I have checked the PNG file in Documents with Finder, so I'm sure it has been modified, but the old one is still in UIWebView.
So, as I think that it's a UIWebView cache problem, I've tried:
[[NSURLCache sharedURLCache] removeAllCachedResponses];
[_webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:url isDirectory:NO ] cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:1]]; or NSURLRequestReloadIgnoringCacheData
None of them works, and I can't change the filename, because the PNG file is used in a lot of places (other html and objc code).
I've tried this too:
some.png?r=randomNumber
but it can't be showed.
How do I clear the UIWebView cache when using a local image file inside a local html?
Other than renaming every file on each access, I've only seen one thing work for this and that is modifying the HTML with javascript to add a timestamp onto the image url so it tricks the webview into thinking it's a different file. Images (usually) load the same no matter what you put after the ? in their url. I think this would be easier than renaming every file each time you load the web view. Something like this (using jQuery):
<img src="myimg.jpg" />
<script>
$(function() {
$('img').each(function(i, el) {
$(el).attr('src', $(el).attr('src')+'?pizza='+(new Date()).getTime());
});
});
</script>
I guess this is assuming that this javascript loads and runs before the images are loaded, but in theory this should work.
For a little background, I've made a page in a webview that used RequireJS to asynchronously load quite a few files. I had the EXACT same problem that this question is talking about except that I was loading javascript files instead of images. The key to fixing this issue was adding a timestamp to every path of javascript file and thus tricking the webview (ex me.js?ts=236136236 and whatever.js?ts=3153524623). I found this to work great.
One other thing I needed to do was add a timestamp to the path of my HTML file when loading it into the webview like this:
[NSURL URLWithString:[[NSString stringWithFormat:#"%#/index.html?pizza=%f", webDirectoryPath, [[NSDate date] timeIntervalSince1970]]
I now can modify all the local files and each time the webview appears the changes come through.
You can try this, in your AppDelegate.m
+(void)initialize {
[[NSURLCache sharedURLCache] setDiskCapacity:0];
[[NSURLCache sharedURLCache] setMemoryCapacity:0];
}
If your html didn't change and the only change was in image you should use UIWebView's reload message instead of loading request again.
Something like this:
- (void)reloadWebView:(id)sender
{
if (self.loaded) {
[self.webView reload];
} else {
NSString *html = [[NSBundle mainBundle] pathForResource:#"web" ofType:#"html"];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:html]];
[self.webView loadRequest:request];
self.loaded = YES;
}
}
You don't even need any manipulations with cache.