Tamarisk
Tamarisk

Reputation: 939

Getting title from WKWebView using evaluateJavaScript

I have a very simple/easy question but have absolutely zero experience with java. I have a WKWebView and I want to get the title text of the page using the javascript document.getElementById.

The webpage I am trying to get the title from has this code:

<html>
<body>
<div class="toolbar">
<h1 id="pageTitle">Schedules</h1>
</div>
</body>
<html>

This code is abridged so I apologize for any errors.

Then I am trying to access the pageTitle in Swift with:

func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {

    webView.evaluateJavaScript("document.getElementById('pageTitle').value") { (result, error) -> Void in
        if error != nil {
            print(result)
        }
    }
}

And the result is returning nil. After hours of searching I still have no idea how to get this to work. Any help is appreciated.

Upvotes: 14

Views: 22396

Answers (6)

superarts.org
superarts.org

Reputation: 7238

As mentioned by @SilkyPantsDan, if you are just interested in the title, there's no need to use JS. Firstly you start observing:

override func viewDidLoad() {
    super.viewDidLoad()
    webView.addObserver(self, forKeyPath: #keyPath(WKWebView.title), options: .new, context: nil)
}

And handle your logic when title is updated:

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "title" {
        title = webView.title
    }
}

Finally you should stop observing if you are supporting iOS 8.0, as observers are not removed automatically before iOS 9.0:

deinit {
    webView.removeObserver(self, forKeyPath: "title")
    //webView.removeObserver(self, forKeyPath: "estimatedProgress")
}

Upvotes: 6

Return Zero
Return Zero

Reputation: 434

this code is works for me :

webView.evaluateJavaScript("document.title').textContent") { (result, error) -> Void in
    if error == nil {
        print(result)
    }
}

Upvotes: 0

LF-DevJourney
LF-DevJourney

Reputation: 28524

In your code when there is some error, then the code will print the result. This'll print nothing when there is no error occuer.

So change you code to this, everything works well.

func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {

    webView.evaluateJavaScript("document.getElementById('pageTitle').innerHTML") { (result, error) -> Void in
        if error != nil {
            print(error)
        }
        print(result)
    }
}

Upvotes: 3

brassic_lint
brassic_lint

Reputation: 11

I used this same code snippet, and worked out the issue... It'll only print the result if it's "nil"!

Try:

webView.evaluateJavaScript("document.getElementById('pageTitle').textContent") { (result, error) -> Void in
    if error == nil {
        print(result)
    }
}

Upvotes: 0

dopcn
dopcn

Reputation: 4218

Use Node.textContent to get a correct copy of text nodes contents.

webView.evaluateJavaScript("document.getElementById('pageTitle').textContent") { (result, error) -> Void in
    if error != nil {
        print(result)
    }
}

Upvotes: 0

SilkyPantsDan
SilkyPantsDan

Reputation: 571

You shouldn't need to use javascript to retrieve the page title. WKWebView has a title property that will retrieve this for you

https://developer.apple.com/library/ios/documentation/WebKit/Reference/WKWebView_Ref/#//apple_ref/occ/instp/WKWebView/title

title The page title. (read-only)

SWIFT var title: String? { get }

The WKWebView class is key-value observing (KVO) compliant for this property.

Available in iOS 8.0 and later.

Upvotes: 38

Related Questions