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
Related
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.
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
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.
I have been using webView delegate successfully from long time. But recently I faced strange issue with this delegate. In my current project I am trying to access my router from webview. I am passing username and password inside URL only. Below is load request code.
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://uname:password#192.168.1.1"]]];
This calls webView delegate method (webViewDidFinishLoad and webViewDidStartLoad) 5 times. Is it expected? When I pass simple URL like google.com it works as expected. But with username and password why these delegate methods are called 5 times?
If this behaviour is correct then I need to know why it calls 5 times only. The reason is, in my program - I am calling performSegueWithIdentifier in webViewDidFinishLoad method and in present form it calls segue 5 times. For workaround I can maintain count and will call performSegueWithIdentifier on 5th count only.
Thanks
webViewDidStartLoad/webViewDidFinishLoad are called once per HTML frame. Your content likely has multiple frames in it.
See UIWebViewDelegate docs.
webViewDidStartLoad:
Sent after a web view starts loading a frame.
This Methods works for me... :)
#pragma mark UI Web View Delegate
NSInteger webViewLoads;
//a web view starts loading
- (void)webViewDidStartLoad:(UIWebView *)webView{
webViewLoads++;
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[SVProgressHUD showWithStatus:#"Loading..." maskType:SVProgressHUDMaskTypeBlack];
}
//web view finishes loading
- (void)webViewDidFinishLoad:(UIWebView *)webView{
webViewLoads--;
[self performSelector:#selector(webViewFinishLoadWithCondition) withObject:nil afterDelay:0.5];
}
//web view handling error
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
webViewLoads--;
NSLog(#"Web View Did Fail Load With Error : %#",error);
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[SVProgressHUD dismiss];
}
-(void)webViewFinishLoadWithCondition{
if(webViewLoads==0){
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[SVProgressHUD dismiss];
}
}
As webViewDidStartLoad/webViewDidFinishLoad are called once per HTML frame, Use an integer to find when the last frame load is finished,
In detail :
Increment the integer in webViewDidStartLoad
Decrement the integer in webViewDidFinishLoad
In webViewDidFinishLoad check when integer is zero, Which means all the frames of web page are loaded, Now call the selector
This is an explanation of #marvin's answer
Best approach:
Check for isLoading in webViewDidFinishLoad and isLoading is false, do what ever u want
-(void)webViewDidFinishLoad:(UIWebView *)webview
{
if (!webview.isLoading)
{
// webview is done loading content.
// `performSegueWithIdentifier` / Your code Here
}
}
My goal is to allow UIWebView load initial link, but disallow any further navigation.
I saw question:
Disable hyperlinks in UIWebView
So, I wired referenced webView property from interface builder.
I specified that my UIViewController uses UIWebViewDelegate:
#interface LegalViewController : UIViewController<UIWebViewDelegate>
In the code, on viewDidLoad, I do following:
mFirstLoad = TRUE;
webView.delegate = self;
And I have following code:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
if (!mFirstLoad)
return FALSE;
mFirstLoad = FALSE;
return TRUE;
}
shouldStartLoadWithRequest is called both initial call and when I click on the link. However, even if shouldStartLoadWithRequest returns FALSE, UIWebView still proceeds and loads a new page.
I see this problem on iOS Simulator 6.0
How can I fix this behavior?
return NO based on type to exclude links
return !(navigationTpe==UIWebViewNavigationTypeLinkClicked);
Is it possible your boolean is getting reset somehow? What happens if you just return NO for (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType?
Here is the same thing which I wrote in comments:
I think I found the reason for the problem. I am not sure how to properly call it (not a big expert on HTML and Javascript). However the link has following code : "<a href="/something" data-transition="flip"</a> As result, callback is called, but it looks like results of this callback is ignored.
As result most likely solution is here: Remove hyperlinks in uiwebview