Search code examples
javascriptiosobjective-cswiftwebkit

How do I repurpose JSContext in UIWebView to WKScriptMessage for WKWebview


I want to convert a UIWebView library to use WkWebview. The remaining piece is switching out JSContext because the valueForKeyPath doesn't work anymore. So how do I rewrite something like the following to use WKScriptMessage as the other SO link suggests? (swift or ObjC answer is fine) How to get JSContext from WKWebView

JSContext *ctx = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];


ctx[@"contentPasteCallback"] = ^(JSValue *msg) {
    __weak typeof(weakSelf) StrongSelf = weakSelf;
    StrongSelf.editorPaste = YES;
};

[ctx evaluateScript:@"document.getElementById('zss_editor_content').addEventListener('paste', contentPasteCallback, false);"];

Solution

  • Ok I figured it out. See the PR https://github.com/nnhubbard/ZSSRichTextEditor/pull/243

    Basically you inject javascript to start the listeners. The key here is to pass the function which calls webkit using postMessage and use the same name, in my case 'jsm' as what was setup when you create the WKUserContentController object

        NSString *pasteListener = @"document.getElementById('zss_editor_content').addEventListener('paste', function() {window.webkit.messageHandlers.jsm.postMessage('paste');});";
    
        [self.editorView evaluateJavaScript:pasteListener completionHandler:^(NSString *result, NSError *error) {
            if (error != NULL) {
                NSLog(@"%@", error);
            }
        }];
    

    and then you listen for the response in the userContentController: didReceiveScript delegate method from WKScriptMessageHandler

    - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    
        NSString *messageString = (NSString *)message.body;
        if ([messageString isEqualToString:@"paste"]) {
            self.editorPaste = YES;
        }