I\'m experimenting with WkWebKit talking back and forth between app and page. I can get javaScript to execute fine using WkWebView evaluateJavascript method, but when I try
I solved it and problem was that if you set userContentController
to a new object, that userContentController
's WKScriptMessageHandler
s will not be registered correctly in Apple's internal code:
WKUserContentController *userContentController = [WKUserContentController new];
userContentController.addScriptMessageHandler(self, name: "jockey")
userContentController.addScriptMessageHandler(self, name: "observe")
webView.configuration.userContentController = userContentController
fixed by using the already instantiated userContentController
by Apple:
webView.configuration.userContentController.addScriptMessageHandler(self, name: "jockey")
webView.configuration.userContentController.addScriptMessageHandler(self, name: "observe")
I ran into this SO because I was experiencing the same issue and this is how I solved it using a custom CustomContentController
(subclass of WKUserContentController
) instance.
let userContentController = CustomContentController()
let webViewConfiguration = WKWebViewConfiguration()
webViewConfiguration.userContentController = userContentController
webView = WKWebView(frame: .zero, configuration: webViewConfiguration)
In my case the CustomContentController
is a subclass of WKUserContentController
in which the add(_ scriptMessageHandler: WKScriptMessageHandler, name: String)
method is called, but I don't believe that is significant.
I believe that the WKUserContentController
must be instantiated and applied to a WKWebViewConfiguration
before the WKWebView is initialized via WKWebView(frame: .zero, configuration: webViewConfiguration)
If the WKWebView has been created and then you try change the WKWebViewConfiguration
you will encounter window.webkit
not being available in the JSContext.
The window.webkit namespace only appears in webview with script message handlers. Make sure that you have called addScriptMessageHandler method of WKUserContentController.
I met the same problem. And after wasting 2 hours, I found this below to work fine. But I don't know why.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
WKUserContentController *userCctrl = [[WKUserContentController alloc] init];
[userCctrl addScriptMessageHandler:self name:@"jscall"];
WKWebViewConfiguration *wbConfiger = [[WKWebViewConfiguration alloc] init];
wbConfiger.userContentController = userCctrl;
CGSize size = [UIScreen mainScreen].bounds.size;
WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 20, size.width, size.height - 20) configuration:wbConfiger];
[self.view addSubview:webView];
webView.UIDelegate = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[webView evaluateJavaScript:@"if (window.webkit === undefined) { alert('未注册的 window.webkit'); } else { window.webkit.messageHandlers.jscall.postMessage({title:'标题'}); }" completionHandler:^(id obj, NSError *error) {
NSLog(@"run js completion with error = %@", error);
}];
});
}
#pragma mark -
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
NSLog(@"run js alert panel message = %@", message);
completionHandler();
}
#pragma mark -
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
NSLog(@"wkwebview run javascript name = %@, body = %@", message.name, message.body);
}