8

Currently I can only figure out how to evaluate javascript by adding it to the webview's configuration's userContentController and reloading the page like so:

WKUserScript *script = [[WKUserScript alloc] initWithSource:source injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
[self.webView.configuration.userContentController addUserScript:script];
[self.webView reload];

How can I execute javascript on my WKWebView similarly to the old WebView's stringByEvaluatingJavaScriptFromString: so that I don't have to reload the page?

I'm trying to get something with the same effect as

[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"document.querySelector('meta[name=viewport]').setAttribute('content', 'width=%d;', false); ", width]];

2 Answers 2

12
[webView evaluateJavaScript:javascriptString completionHandler:nil];

performs the same function as the one you have listed for UIWebView

Sign up to request clarification or add additional context in comments.

Comments

9

You can only set the WKWebViewConfiguration at init time via the initializer

[[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];

All calls to the property configuration are copied in a later stage of runtime (see docs and Header file). So basically what you´re doing with your first three lines of code is to set the WKUserScript to a WKWebViewConfiguration which is never used - and therefore not working.

The right way to do it:

NSString *scriptString = @"Some javascript";
WKUserScript *script = [[WKUserScript alloc] initWithSource:scriptString injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
WKUserContentController *userContentController = [[WKUserContentController alloc] init];
[userContentController addUserScript:script];
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
configuration.userContentController = userContentController;
_webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];

After doing this, you won´t need evaluateJavaScript: anymore.

P.S.: I´m using this code in my little project STKWebKitViewController on GitHub. Maybe this will save you time, too!

4 Comments

what if you need to make consecutive calls to the web page? Would you call addUserScript every time?
Please define "consecutive". This approach runs the same JavaScript(s) on every page load. If you want to alter which scripts are being executed, evaluateJavaScript: may be the better solution for you.
Say you need to call the function and pass the current timestamp as an argument on every uibutton click.How would you do it?
Definitely evaluateJavaScript:! As you can see in the above code, with the WKUserScripts it´s only possible to execute at document start or end, not for custom events such as button clicks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.