Wkwebview Didn't Finish Loading, When Didfinishnavigation Is Called - Bug in Wkwebview

WKWebView didn't finish loading, when didFinishNavigation is called - Bug in WKWebView?

WKWebView doesn't use delegation to let you know when content loading is complete (that's why you can't find any delegate method that suits your purpose). The way to know whether a WKWebView is still loading is to use KVO (key-value observing) to watch its loading property. In this way, you receive a notification when loading changes from true to false.

Here's a looping animated gif showing what happens when I test this. I load a web view and respond to its loading property through KVO to take a snapshot. The upper view is the web view; the lower (squashed) view is the snapshot. As you can see, the snapshot does capture the loaded content:

Sample Image

[NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
if (self->_webKitView.isLoading == true) {
NSLog(@"Still loading...");
}else {
NSLog(@"Finished loading...");
[timer invalidate];
dispatch_async(dispatch_get_main_queue(), ^{
[self->_activityIndicator stopAnimating];
});
}
}];

WKWebView Content loaded function never get called

You are not setting the navigationDelegate. Set it and it should be fine.

class ViewController: UIViewController, WKNavigationDelegate {

override func viewDidLoad() {
super.viewDidLoad()

let noLayoutFormatOptions = NSLayoutFormatOptions(rawValue: 0)

let webView = WKWebView(frame: CGRectZero, configuration: WKWebViewConfiguration())
webView.setTranslatesAutoresizingMaskIntoConstraints(false)
webView.navigationDelegate = self
view.addSubview(webView)

view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[webView]|", options: noLayoutFormatOptions, metrics: nil, views: ["webView": webView]))

view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[webView]|", options: noLayoutFormatOptions, metrics: nil, views: ["webView": webView]))

let url = NSURL(string: "http://google.com")
let request = NSURLRequest(URL: url)
webView.loadRequest(request)
}

func webView(webView: WKWebView!, didFinishNavigation navigation: WKNavigation!) {
print("Finished navigating to url \(webView.url)");
}

}

And here is a bit better version with Swift 3.

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

let configuration = WKWebViewConfiguration()
let webView = WKWebView(frame: .zero, configuration: configuration)
webView.translatesAutoresizingMaskIntoConstraints = false
webView.navigationDelegate = self
view.addSubview(webView)

[webView.topAnchor.constraint(equalTo: view.topAnchor),
webView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
webView.leftAnchor.constraint(equalTo: view.leftAnchor),
webView.rightAnchor.constraint(equalTo: view.rightAnchor)].forEach { anchor in
anchor.isActive = true
}

if let url = URL(string: "https://google.com/search?q=westworld") {
webView.load(URLRequest(url: url))
}
}

}

extension ViewController: WKNavigationDelegate {

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("Finished navigating to url \(webView.url)")
}

}

Hiding view when WKWebView has finished loading swiftUI

Your View won't know to reload unless it is triggered with something like a @State property or an ObservableObject. You haven't really provided enough code from your SwiftUiWebView to show everything, but here's the gist of what needs to happen:

struct ContentView: View {
@State var webViewFinishedLoading = false

var body: some View {
SwiftUiWebView(url: URL(string: "myUrl"), finishedLoading: $webViewFinishedLoading)
ZStack {
if (!webViewFinishedLoading) {
....
}
}
}
}
struct SwiftUiWebView : UIViewRepresentable {
var url: URL
var finishedLoading: Binding<Bool>

//...
}

Then, you will need to pass that finishedLoading Binding to your web view delegate and set its .wrappedValue to true when you're done loading:

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
if (webView.isLoading) {
return
}
print("Done Loading")
finishedLoading.wrappedValue = true
}

Because it's tied to a @State variable, your view will know to refresh.

WKWebView Navigation Delegate Not Called

You need to move let test = TestWebview () to class level, otherwise this object is going to be evicted when viewDidLoad completes: the navigationDelegate is defined as weak, so it's not going to prevent it either.

How to check if wkwebview finished loading in UItest

I had some problems trying to figure out how to make it too, so I decide to use this work around. In the wkwebview didfinishload if you have any variable there, you can check if it exists or its value. If you do not have any variable there, you must create it in global scope, right? For example if we have this code when wkwebview ends loading:

func webView(_ webView: WKWebView,didFinish navigation: WKNavigation!) {
myTopLabel.text = "Content Loaded"
print("loaded")
}

'myTopLabel' is a UILabel that I use to show the status of my web, so what I had to do is execute this command in UITest:

let nextGameLabel = self.app.staticTexts["Content Loaded"]
app.buttons["Reload Web"].tap()
XCTAssert(nextGameLabel.waitForExistence(timeout: 5))

So When I press the app button, the UITest waits for 5 seconds to see if the web is loaded or not. Hope it helps dude.

WKWebView not working

// Add plist file 
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>google.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>


 if WKWebView don't not support then declare .m file below code:

#import <WebKit/WebKit.h>

@interface WebScannerViewController()
{

WKWebView *webView;

}

@end

@implementation WebScannerViewController

- (void)viewDidLoad

{

[super viewDidLoad];
webView.hidden=YES;

webView.UIDelegate = self;
webView.navigationDelegate = self;
self.loadingSign.hidden = NO;

webView.frame=CGRectMake(0, 94, Width, Height-128);

}

Setting loading call backs to WKWebView

You could do this in navigationDelegate of WKWebView.

// your ViewController should adopt WKNavigationDelegate protocol
self.wkwebView.navigationDelegate = self

func webView(_ webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {
// similar to webViewDidFinishLoad:
}


Related Topics



Leave a reply



Submit