简体   繁体   中英

Injecting global object in WKWebView

I'm attempting to add a global object to a WKWebView where the loaded HTML expects a certain object to be present (with an API). I have the following setup to prime the HTML after loading. This works in this following trivial example, but with the 'real' content loaded with loadRequest it fails with "[Error] ReferenceError: Can't find variable". Anyone have a similar experience?

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupWebView];
}

- (void)setupWebView
{
    WKWebViewConfiguration *webConfiguration = [[WKWebViewConfiguration alloc] init];
    WKUserContentController *userContentController = [[WKUserContentController alloc] init];

    NSString* jsCode =
    @"var TheObject = function() {}; \
    TheObject.prototype.sendTheMessage = function() { \
      window.webkit.messageHandlers.performAction.postMessage(messageToPost); \
    }; \
    var theObject = new TheObject();";

    WKUserScript *userScript = [[WKUserScript alloc] initWithSource:jsCode
                                                      injectionTime:WKUserScriptInjectionTimeAtDocumentStart
                                                   forMainFrameOnly:NO];
    [userContentController addUserScript:userScript];
    [userContentController addScriptMessageHandler:self
                                              name:@"performAction"];
    webConfiguration.userContentController = userContentController;

    self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds
                                      configuration:webConfiguration];
    [self.view addSubview:self.webView];

    [self.webView loadHTMLString:
     @"<body onload='sendMessage()'> \
     <script>function sendMessage() { \
       theObject.sendTheMessage(); \
     } \
     </script> \
     Attempting to send the message \
     </body>" baseURL:nil];
}

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
    NSLog(@"%@", message);
}

@end

The only difference with the example and my production code was the fact that I loaded the javascript to be injected from a file. And in this file there was a typo. Goes to show that trying to reduce the problem down to example code helps identify your silly mistakes!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM