Did finish navigation load multiple times - ios

I am using WKWebView to load a URL but my didFinishNavigation class multiple times.
I have to evaluate javascript and I had to wait for page to load complete and then have to inject JS in it but it fires multiple times.
-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
[_webView evaluateJavaScript:js completionHandler:nil];
}
js is the string in which I have written my JS code.

If you are using UIWebView, after the web view has finished loading, it is calling the delegate method:
func webViewDidFinishLoad(_ webView: UIWebView)
Try it.

Related

UIWebView objectivists-c using webkit showing depreciated on viewdidload

I'm trying to create a UIWebView in objective-c . I get deprecation error so I tried to use recommended webkit WkWebview but at a point I still get error here
- (void)webViewDidFinishLoad:(UIWebView *)webView{
}
I have tried using it this way but yet get new error Implementing deprecated method
- (void)webViewDidFinishLoad:(WKWebView *)webView{
}
The WKWebView version of webViewDidFinishLoad is this: (in Objective-C syntax)
- (void)webView:(WKWebView *)webView
didFinishNavigation:(WKNavigation *)navigation {
}
Replacing the UIWebView name with WKWebView on the delegate method webViewDidFinishLoad doesn't work as it is the delegate method for UIWebView. You need to use the original delegate method for WKWebView.
As per documentation, you should use
func webView(_ webView: WKWebView,
didFinish navigation: WKNavigation!)
instead of
- (void)webViewDidFinishLoad:(UIWebView *)webView{
}
On migrating to WKWebView you can refer this

how can I clear the contents of a UIWebView/WKWebView?

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

Can we use HTML code in SWIFT?

I have some attractive graph which is made in HTML and javascript.
So my questions are:
Can I use this work in my swift app,
Can we use javascript and html code to make graph in app?using webview
Can we pass values from swift/objective c code to javascript/html code and vice-versa?
If yes , How can we pass variable value to html/javascript and how to to accept this value in HTML
html text can be embedded into labels as NSAttributedString instances
HTML content that has scripts and stuff can be put into a web view container: UIWebView or WKWebView
YES. Create a webview then load this html page.
YES. (same as answer 1)
YES .
To send to html page: call [webView stringByEvaluatingJavaScriptFromString:function];
To send to swift/objective-c : handle shouldStartLoadWithRequest of your UIwebview.
-(BOOL) webView : (UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *) request navigationType : (UIWebViewNavigationType)navigationType {
if ([[[request URL] absoluteString] hasPrefix:#"yourPrefixe:"]) {
//do your works
//then cancel current request
return NO;
}
return YES;
}

Disable WKActionSheet on WKWebView

I'm migrating an iOS app form UIWebView to WKWebView. So far so good... In the previous app I disabled long press and implemented a custom long press (to do custom handling of links), however I can't get this working in the WKWebView
I've tried the following:
- (void)webView:(WKWebView *)wkWebView didFinishNavigation:(WKNavigation *)navigation {
[wkWebView evaluateJavaScript:#"document.body.style.webkitTouchCallout='none';" completionHandler:nil];
}
I've checked and that line gets executed, the response of the call is #"None"
But it responds with:
Warning: Attempt to present on whose view is not in the window hierarchy!
Any ideas?
SOLUTION:
Inject javascript into wkwebview now works!
[self.wkWebView evaluateJavaScript:#"document.body.style.webkitTouchCallout='none';" completionHandler:nil];
This is the solution in Swift 3.0:
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webView.evaluateJavaScript("document.body.style.webkitTouchCallout='none';")
}
myWkWebView.allowsLinkPreview = false
I haven't verified it, but it looks like you can also use CSS to disable this functionality:
-webkit-touch-callout: none;
Source: https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-touch-callout

UIWebView throwing Frame load interrupted error

I am working on application in which I am downloading file and saving it in documents directory
so when user uses the application next time he can directly open the file which are already downloaded
I am showing that file on next screen in UIWebView using follwing code :
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:self.url]; // where url is url of file in documents directory
[webView loadRequest:urlRequest];
This is working perfectly for file having extension pdf but there are some files with extension asp and
when I am trying to open those file I get this error
Error
Domain=WebKitErrorDomain Code=102 "Frame load interrupted"
UserInfo=0x9b58fa0
{NSErrorFailingURLKey=file:///Users/poonam/Library/Application%20Support/iPhone%20Simulator/7.1/Applications/7EE726E5-5315-4BEE-9629-F85FBCD46BC3/Documents/V2_076eb8847184be9e441f1bed7cc1a705.asp,
NSErrorFailingURLStringKey=file:///Users/poonam/Library/Application%20Support/iPhone%20Simulator/7.1/Applications/7EE726E5-5315-4BEE-9629-F85FBCD46BC3/Documents/V2_076eb8847184be9e441f1bed7cc1a705.asp,
NSLocalizedDescription=Frame load interrupted}
To solve this I tried
- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
if ([url.scheme isEqualToString:#"file"]) {
NSLog(#"Open start page");
[[UIApplication sharedApplication] openURL:url];
return NO;
}
return YES;
}
But However I am not able to solve my problem. Any suggestions please
Finally after spending hours on this , Here i found the solution for this common Webview "frame load interrupted" issue:
Download the file in bytes form
Store it in the Local Storage
Load the file in Web view with the local path and it works
Code for the above steps:
https://stackoverflow.com/a/59194408/12483992
Late answer but this could be useful for someone.
I got this same error and it was because I didn't realize I was returnint false in
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool
in my UIWebView Delegate. Changed to
return true
fixed the issue and
func webViewDidFinishLoad(_ webView: UIWebView)
was called after that.

Resources