iOS UIWebview does not load new css - ios

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!

Related

Cannot load local html file into WKWebView on ios device (not simulator) [duplicate]

This question already has answers here:
Load local web files & resources in WKWebView
(5 answers)
Closed 3 years ago.
I'm having troubles with the following code. It's supposed to load a local HTML file into a WKWebView.
It works fine on any simulator I've tried (ios 12 / ios 13).
For a reason I do not understand yet, it does not work on device.
Instead, I get a blank screen. Debugging the webview with the Safari debugger shows that the page is "about:blank". It did not load my file... Why ?
Note that I have checked the existence of the file by downloading the app container from the phone and the file is there...
- (void)loadIndexConteneurWithHash:(NSString *)hash
{
NSString *fileName = #"index.html";
NSString *subpath = hash ? [NSString stringWithFormat:#"%##%#", fileName, hash] : fileName;
NSString *rootContainerDirectoryPath = [NSFileUtility pathRelativeToContentDirectoryForSubpath:#"/www/v2"];
NSURL *URL = [NSURL URLWithString:subpath relativeToURL:[NSURL fileURLWithPath:rootContainerDirectoryPath]];
[[NSURLCache sharedURLCache] removeAllCachedResponses];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10.0f];
[self.webView performSelectorOnMainThread:#selector(loadRequest:) withObject:request waitUntilDone:true];
}
Edit: this question is NOT a duplicate of Load local web files & resources in WKWebView
I do not load my HTML file from the bundle but from the app container as noted originally in my question. I've also tried the loadFileURL method and it does not work either.
In order to access a Local ressource you have to use :
Bundle.main.url(forResource: "MyFile", withExtension: "html")

WKWebView gives SecurityError when bundling html and javascript with app

We are trying to migrate a hybrid app from UIWebView (iOS < 8) to WKWebView (iOS 8), but we are getting SecurityErrors when trying to store stuff using the DOM WebDatabase API (i.e. 'web sql databases').
The following throws an error if the index.html has been loaded from a bundled file with the app
// throws SecurityError: DOM Exception 18
var db = openDatabase('mydb', '1.0', 'key value store', 1);
The same code works fine with UIWebView. I can fallback to using Local Storage for some reason, but using WebSQL databases is a no go. I can only speculate that this has something to do with the same origin policy or something related.
The funny thing is that loading index.html from the network works fine :-/
Any clues as to how I can work around this? Any options to set on the WKWebView that fixes it?
This is how we load the web related stuff:
NSString *htmlPath = [[NSBundle mainBundle] pathForResource:#"index" ofType:#"html"];
NSURL *baseURL = [NSURL fileURLWithPath:htmlPath];
NSURLRequest *request = [NSURLRequest requestWithURL:baseURL];
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
[config.userContentController addScriptMessageHandler:self.myCallbacks name:#"NativeApp"];
self.webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:config];
[self.webView loadRequest:request];
The html file simply loads a javascript file that has a relative path, "myCode.js".
There is an issue (OpenRadar) with WKWebView in iOS 8.0 (and 8.1 B1, I think) that prevents it from loading local files. It might be affecting local storage too. See this question for more details.
You can fix this by adding the following method to the UIDelegate of your WKWebView.
- (void) _webView:(WKWebView *)webView
decideDatabaseQuotaForSecurityOrigin:(WKSecurityOrigin *)securityOrigin
currentQuota:(unsigned long long)currentQuota
currentOriginUsage:(unsigned long long)currentOriginUsage
currentDatabaseUsage:(unsigned long long)currentUsage
expectedUsage:(unsigned long long)expectedUsage
decisionHandler:(void (^)(unsigned long long newQuota))decisionHandler {
decisionHandler(1024*1024*50); //default to 50MB
}
It gives all databases a quota of 50MB, instead of the default of 0 which allows them to be opened. This behavior isn't documented, so I don't know where Apple stands with this.
Also, it appears this issue will be fixed in iOS 10.
I've made a 'plugin' that allows you to use WebSQL (more an implementation of it) in the WKWebView. It can be found here
https://github.com/ajwhiteway/WKWebSQL
import WKWebSQL
.
.
.
var webView = WKWebView(frame: view.frame, configuration: WKWebViewConfiguration())
WKWebSQL.LoadPlugin(webView)
To get it loaded into the page. Versioning isn't really supported at this time. Feel free to add it.

Unable to display macro enable word file in UIWebview

I'm trying to display MS office files(word,powerpoint,excel) using UIWebview some of the files have macros enable UIWebview is unable to display these files any idea why this happen? is there a way to make UIWebview render these files?.
Note: I do not want the macros to work if i can display the content of the file that will be enough.
I know this is old, but I ran into it today. It looks UIWebView will NOT open macro-enabled Office files directly. For example, the following code fails -
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:filePath]]];
The code above fails ONLY for macro-enabled Office files - it works just fine for .docx, .pptx, .rtf, .pdf, .txt, etc. files. However, if we pull the file into NSData and then provide the mime type explicitly to UIWebView, the file will open. The code below will open these macro-enabled Office files -
// this will open a .pptm file - replace mime type as necessary for other macro-enabled file types
NSData* fileData = [NSData dataWithContentsOfFile:filePath];
[webView loadData:fileData MIMEType:#"application/vnd.ms-powerpoint.presentation.macroEnabled.12" textEncodingName:nil baseURL:nil];
Tested with .pptm, .ppsm, .potm, .docm, .xlsm

Clear UIWebView cache when use local image file

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.

Localization XCode 4.5 + language-specific PDF loaded in main UIWebView / IOS

I'm working on a bilingual simple IOS App: a PDF file is loaded in a UIWebView with the method described here:
Loading Local PDF File Into WebView
In XCode, using the "Localization" feature, I added a second language (French). The MainStoryboard contains 2 "sub" storyboards, one for English, and one for French.
In the MainStoryboard (English), I inserted a UIWebview --> connect that view to the MainViewController.h --> add the code for inserting the English PDF file in the MainViewController.m:
NSString *path = [[NSBundle mainBundle] pathForResource:#"EnglishBook" ofType:#"pdf" inDirectory:#"PDFBooks"];
NSURL *url = [NSURL fileURLWithPath:path];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[_UIWebViewBook loadRequest:request];
[_UIWebViewBook setScalesPageToFit:YES];
The English version runs well.
But... where to put the French PDF file ?
Is there a way to target a language-specific PDF file ?
Could "pathForResource:#" be "language" sensitive ?
Thanks for your help !
NSString *path = [[NSBundle mainBundle] pathForResource:#"Book" ofType:#"pdf" inDirectory:#"PDFBooks"];
NSURL *url = [NSURL fileURLWithPath:path];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[_UIWebViewBook loadRequest:request];
[_UIWebViewBook setScalesPageToFit:YES];
Make the request for a single book, then in your project folder make a subfolder en.lproj and fr.lproj add the English version French version respectively and drag both into your Xcode project.
They will both appear, under en.lproj and fr.lproj, then depending on the device localisation, the correct one should load.
To Clarify. In Finder set up this directory structure:
When you then drag MyBook.txt (pdf in your case) to Xcode, it will look like:
Then when you call for MyBook.txt the device will automatically chose which version to grab, depending on the devices international language settings (Settings-General-International-Language).
You might also want to look into UIDocumentInteractionController for documents.

Resources