0

when using a UIWebView I want to detect the moment a web page finishes loading in an iOS app. For that I tried to use the solution mentioned in this post.

But the problem is that the webViewDidFinishLoad() function gets called (almost right after the call to loadRequest()) way before the page appears on the display making the solution useless. Am I missing something? Or is there a better (or different) way?

P.S. I am using Xcode Version 8.3.2 and iOS Version 10.3.2

Michel
  • 10,303
  • 17
  • 82
  • 179
  • Looks your moment html page has an async way to load content, that's why the webViewDidFinishLoad() function is called very fast. – Yun CHEN May 25 '17 at 02:37
  • I am just loading an arbitrary web page in a UIWebView within an iOS app, and not aware of any so called moment.html page. Forgive me please the lack of knowledge. Where can I check this moment.html? – Michel May 25 '17 at 04:36
  • Open the url in a Web Browser, like Chrome, Safari. And then right click the page, choose "Check page source code" , then you are able to check the html source code. – Yun CHEN May 25 '17 at 05:29
  • That does not answer my question. I want my iOS app to work whatever page the user is going to open, the app cannot be depending on the way the chosen page is written. I am concerned with writing the iOS app not with writing some web page. – Michel May 25 '17 at 05:55
  • Since you cannot control the content of web page, you cannot control the timing of calling webViewDidFinishLoad() very exactly. Maybe there is a JS task in web page needs 1 min to do the job, but web page is finished load in 1 second. – Yun CHEN May 25 '17 at 06:09
  • Well, you may be right, but in that case I do not really see why webViewDidFinishLoad() exists. – Michel May 25 '17 at 06:16
  • It's working well for normal situations, usually, it will be called properly after loading an ordinary web page which is without the JS like I said above. – Yun CHEN May 25 '17 at 06:36
  • OK. The link I was using as a test is this: http://en.m.wikipedia.org – Michel May 25 '17 at 08:33
  • I have tested this link. webViewDidFinishLoad() is called after finished loading exactly. The delay is obviously. Maybe where to send the request in your code is wrong. – Yun CHEN May 25 '17 at 08:52
  • OK, thanks; then I must be doing something wrong somewhere. – Michel May 25 '17 at 08:55
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/145105/discussion-between-michel-and-yun-chen). – Michel May 25 '17 at 08:56

1 Answers1

0

The every page of HTML content loaded webViewDidFinishLoad will called... So I put three types of validation. Use it which one is preferred for you.

var webViewPages = 0

func webViewDidStartLoad(_ webView: UIWebView) {
    webViewPages += 1
}

func webView(_ webView: UIWebView, didFailLoadWithError error: Error) {
    webViewPages -= 1
}

func webViewDidFinishLoad(_ webView: UIWebView) {

    if (webView.isLoading){
        return
    }

    if webView.stringByEvaluatingJavaScript(from: "document.readyState") != "complete"{
        return
    }

    webViewPages -= 1

    if webViewPages > 0{
        return
    }
    // Calculating webview height
    let height = Int(webView.stringByEvaluatingJavaScript(from: "document.body.scrollHeight")!)

}
Bala
  • 1,224
  • 1
  • 13
  • 25
  • In my case webViewDidFinishLoad() is only called once (far too soon), so I don't have any choice of checking something inside like you seem to be doing in your code. – Michel May 25 '17 at 06:13
  • What can I share which is relevant except this: func webViewDidFinishLoad(_ webView: UIWebView) { print(#function + " Hi, we are done!") } – Michel May 25 '17 at 08:37
  • This won't actually tell you when the page has been rendered, as I remember, there is no reliable way to know this. – James P May 25 '17 at 09:47