0

I have an image-heavy web page I'm loading through a UIWebView. I display a spinner on webviewdidstartLoad and dismiss on webviewdidfinishLoad.

It's working OK, but the thing is, webviewdidfinishLoad doesn't get called until all the images on the page have been loaded.

Is there a way to detect DOM ready event so I can dismiss the spinner right after all the DOM elements have been loaded? Waiting for all the images takes too much time..

Vlad
  • 8,038
  • 14
  • 60
  • 92

2 Answers2

2

Straightforward to do. However - and I know this doesn't answer the question specifically - the first thing is to use WKWebView rather than UIWebView.

Then, set up a KVO on one of the properties, estimatedProgress:

override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject: AnyObject], context: UnsafeMutablePointer<Void>) {
    if keyPath == "estimatedProgress"
    {
        if let webView = object as? WKWebView
        {
            webView.evaluateJavaScript("document.readyState == \"interactive\"", completionHandler:{ (isLoaded:AnyObject!, error:NSError!) -> () in
                if let l = isLoaded as? Bool where l
                {
                    println("Loaded!")
                }
        }
    }
}

Take a look at these answers regarding readyState:

How to detect if DOMContentLoaded was fired

Javascript - How to detect if document has loaded (IE 7/Firefox 3)

Because we're working with Safari, or rather WebKit - the same engine as Safari - the above Swift code runs a JavaScript evaluation of:

document.readyState == "interactive"

This line;

if let l = isLoaded as? Bool where l

optionally casts the resulting optional to a Bool and checks that it is true before printing out "Loaded!" to the console.

Community
  • 1
  • 1
Max MacLeod
  • 26,115
  • 13
  • 104
  • 132
  • 1
    You should note that the `if l = isLoaded as? Bool where l` only works on Xcode 8.3 beta with Swift 1.2 beta. That syntax is not yet available on the production Xcode 6.1.1. – Stefan Arentz Feb 25 '15 at 02:52
0

Check out WKWebKit to replace UIWebView if you only need to support iOS 8 and above. You can inject a javascript that runs on DOM ready and then the script can communicate with your app. See the NSHipster page on the topic for more info: http://nshipster.com/wkwebkit/

ozz
  • 1,137
  • 7
  • 9