my code looks like
if([[self cache] isEqualToNumber:[[NSNumber alloc] initWithInt:1]])
{
[[NSURLCache sharedURLCache] setDiskCapacity:4 * 1024 * 1024];
[[NSURLCache sharedURLCache] setMemoryCapacity:32 * 1024 * 1024];
[self setRequestObj:[NSURLRequest requestWithURL:loadUrl cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]];
}
else [self setRequestObj:[NSURLRequest requestWithURL:loadUrl cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0]];
My else part does not work. Why is my UIWebView not ignoring my local cache?
Every time I visited a testsite my app does not load from the original source. He only load the index.html but the linked images only at first visit.
What's my issue?
The NSURLRequestReloadIgnoringLocalCacheData flag affects only that one request, not future requests. So this works as expected. If you want to disable other caching, the only way I know of to do that is by implementing an NSURLProtocol that intercepts the HTTP/HTTPS requests, modifies them in an identifiable way (e.g. adding a custom header), and then re-sends them. This is not for the faint of heart.
You're probably better off just purging the cache: How to clear UIWebView cache?
I had the same problem I think it is probably a UIWebView bug. Because after I changed it WKWebView, NSURLRequestReloadIgnoringLocalCacheData works!
Related
I have a WKWebView that loads a local set of webpages using WKWebViewConfiguration to set the configuration for #"allowFileAccessFromFileURLs" to be true.
The request is set up with something like this:
NSURL *url = [[NSBundle mainBundle] URLForResource:#"testPage" withExtension:#"html" subdirectory:#"html/pages"];
NSURLRequest *req = [[NSURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10.0f];
Then the request is sent using the following WKWebview method:
- (nullable WKNavigation *)loadRequest:(NSURLRequest *)request;
my problem is where the device has a current connection but there is no network traffic. The webview as an element on the screen will be added to the screen and the request will be made but the webview will show a white screen for about 50 seconds before displaying the local content.
Everything in the webview loads regardless of the network status as its loaded locally when there is no link conditioner set.
For example if the device is connected to wireless but the network link conditioner is set to 100% loss. The webview is created and the request is sent to load the local content triggering the hang of the load.
I had a thought that it might be the WKWebView trying to do some kind of validation in the background that requires a network transaction but I did some network profiling with instruments and also some timeline recording in the safari webview and I couldnt see anything that would cause it to hang.
The only reason I can think of it loading local content after 50 seconds or so is that its hit some sort of WKWebView timeout to load a network connection.
Any help would be greatly appreciated, thanks.
Okay so for anyone else who stumbles across this I have found what I was doing wrong.
The issue was not actually the WKWebview or the web content itself it was how I was handling the completion of the webview loading.
in the method:
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation{
I was listening for a completion of events by evaluating some JS like so:
-(void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation
{
[webView evaluateJavaScript:#"document.body.innerHTML" completionHandler:^(id result, NSError *error)
{
if (result != nil) {
[self doCertainNetworkEvent]; //here another method is called with a networking function inside of it.
}
if(error)
{
NSLog(#"evaluateJavaScript error : %#", error.localizedDescription);
}
}];
}
The completion block of course couldnt finish until the network function within the didFinishNavigation method call was finished (which it couldnt because there was no traffic.)
I have a webview that can be cycled through different URLs. When I switch from one to the other I want the old web page to disappear before loading the next one. How can I do this without re allocating the webview?
If I try to [self.webView loadHTMLString:#"" baseURL:nil]; and load my URL in the same function the previous web page still remains:
[self.webView loadHTMLString:#"" baseURL:nil];
[self.webView loadRequest:[NSURLRequest requestWithURL:self.pageURL]];
EDIT: this apparently isn't clear enough for you. the below code doesn't clear the webview, it displays the previous page until the new one is loaded:
- (void) startLoadOfNextURL:(NSURL*)url
{
// clear:
[self.webView loadHTMLString:#"" baseURL:nil]; //DOESNT WORK
// Load real next URL
NSURLRequest* request = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:request];
}
You can write the code below while your controller dismisses.
webView.load(URLRequest(url: URL(string:"about:blank")!))
You can make it load a blank page
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"about:blank"]]];
Use JavaScript instead.
webView.evaluateJavaScript("document.body.remove()")
The following code clears the screen and then navigates
Swift
webView.evaluateJavaScript("document.documentElement.remove()") { (_, _) in
self.webView.load(urlRequest)
}
To clear old contents of webview
When you call - loadHTMLString:baseURL: it doesn't block until the load is complete. Once it records your request, it returns and loads in the background.
As a result, you would need to wait for the first load to finish before kicking off a new load request.
With UIWebView you would use UIWebViewDelegate's
- webViewDidFinishLoad:.
With WKWebView you would use WKNavigationDelegate's
- webView:didFinishNavigation:
Another approach if you really wanted to clear the contents without a delegate method would be to use JavaScript (eg https://stackoverflow.com/a/4241420/3352624). Then for UIWebView you could invoke - stringByEvaluatingJavaScriptFromString:. That method will block execution until the JavaScript executes and returns.
For WKWebView, you would need to do something like https://stackoverflow.com/a/30894786/3352624 since its - evaluateJavaScript:completionHandler: doesn't block.
To make old contents "disappear"
If you really just want to make "the old web page to disappear", you could cover the content area of the webview with a blank UIView temporarily. You could hide the contents when you initiate the load and then show the contents using the delegate methods above after the load completes.
Swift
webView.load(URLRequest(url: URL(string: "about:blank")!))
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: {
//Load request or write code here
})
I have a UIWebView that loads a PDF document, like this:
NSURL *myUrl = [NSURL URLWithString:#"http://www.site.com/myPDF.pdf"];
NSURLRequest *myRequest = [NSURLRequest requestWithURL:myUrl];
// Clear Cache, to insure prompt update of PDF
[[NSURLCache sharedURLCache] removeCachedResponseForRequest:myRequest];
[myWebView loadRequest:myRequest];
When my internet connection is off, i get nothing. Just a blank UIView. Is there any way i can detect when there is not internet connection, or check if the URLContents is empty? I am trying to call a method -(void)showErrorText to show text in the center screen. How would i do this? (I got the method complete, just not the internet check). THANKS.
You can try to set the delegate of the webView to self and implements the webView:didFailLoadWithError and the others delagate methods tout have more details.
I've got a UIWebView that's loading a simple request like so:
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"derp.com"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:15.0];
[webView loadRequest:theRequest];
I have another method that executes some JavaScript on the webView. This method may be called multiple times from different sources (including webViewDidFinishLoad and viewDidAppear). To protect against errors I have wrapped this in an if statement like so:
if (!self.webView.loading) {
... do stuff....
}
The problem is self.webView.loading is ALWAYS 0. I have even tried to set up an observer (tried a few different variations.... not 100% sure of the sytnax):
[self addObserver:self forKeyPath:#"webView.loading" options:0 context:NULL];
But observeValueForKeyPath:ofObject:change:context: never gets called.
Better to implement the UIWebViewDelegate methods...
Set the delegate in viewDidLoad:
[webView setDelegate:self];
You can use
- (void)webViewDidFinishLoad:(UIWebView *)webView {
//do things once loaded }`
To get a call back when the load has completed and it's much more reliable than messing with KVO.
by looking at UIWebView doc
isLoading = YES If the receiver is still loading content; otherwise, NO.
Then, is it possible that at this point the loading of your web view is already finished ?
I'm trying to load documents into my app for display and this works if they're stored locally but not from the server. I'm testing with MAMP. Here's my viewDidLoad method:
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *myUrl = [NSURL URLWithString:#"http://localhost:8888/FilesForApp/Docs/MS.doc"];
NSURLRequest *myRequest = [NSURLRequest requestWithURL:myUrl];
[_webView loadRequest:myRequest];
}
Can anyone point tell me if there's something missing from this?
-EDIT-
Forgot to add, it doesn't crash, just shows a plain, white display.
Make sure you can access that doc through your web browser(make sure the doc exists).
Try to add the http:// prefix.
Don't forget to add _webView as subView to your view.
Don't forget to set the _webView's frame.