web-dev-qa-db-fra.com

Comment obtenir JSContext à partir de WKWebView

Dans UIWebView, je peux obtenir JSContext via:

[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]

La même manière ne fonctionne pas dans WKWebView et l'application se bloque lorsqu'elle arrive sur cette ligne de code.

Existe-t-il un moyen d'obtenir JSContext dans WKWebView?

merci d'avance.

28
Xiong

Vous ne pouvez pas obtenir le contexte, car la mise en page et le javascript sont gérés sur un autre processus.

Au lieu de cela, ajoutez des scripts à votre configuration de vue Web et définissez votre contrôleur de vue (ou un autre objet) comme gestionnaire de messages de script.

Maintenant, envoyez des messages à partir de JavaScript comme ceci:

window.webkit.messageHandlers.interOp.postMessage(message)

Votre gestionnaire de messages de script recevra un rappel:

- (void)userContentController:(WKUserContentController *)userContentController 
                            didReceiveScriptMessage:(WKScriptMessage *)message{
    NSLog(@"%@", message.body);
}
10
Leo Natan

configurez votre wkwebview comme ceci et ajoutez le gestionnaire en conséquence et postez le message du script de façon similaire

NSString *myScriptSource = @"alert('Hello, World!')";


WKUserScript *s = [[WKUserScript alloc] initWithSource:myScriptSource injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES];
WKUserContentController *c = [[WKUserContentController alloc] init];
[c addUserScript:s];
// Add a script message handler for receiving  "buttonClicked" event notifications posted from the JS document using window.webkit.messageHandlers.buttonClicked.postMessage script message
[c addScriptMessageHandler:self name:@"buttonClicked"];

WKWebViewConfiguration *conf = [[WKWebViewConfiguration alloc] init];
conf.userContentController = c;

WKWebView *webview = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:conf];
[self.view addSubview:webview];
webview.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
// Do any additional setup after loading the view, typically from a nib.
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://google.com"]];
[webview loadRequest:request];

implémenter le gestionnaire de messages de script "WKScriptMessageHandler" avec le nom de la méthode

#pragma mark -WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message          {
if ([message.name isEqualToString:@"buttonClicked"]) {
self.buttonClicked ++;
}

// JS objects are automatically mapped to ObjC objects
id messageBody = message.body;
if ([messageBody isKindOfClass:[NSDictionary class]]) {
NSString* idOfTappedButton = messageBody[@"ButtonId"];
[self updateColorOfButtonWithId:idOfTappedButton];
}
}

et poster le formulaire de message js comme celui-ci

var button = document.getElementById("clickMeButton");
button.addEventListener("click", function() {
    var messgeToPost = {'ButtonId':'clickMeButton'};
    window.webkit.messageHandlers.buttonClicked.postMessage(messgeToPost);
},false);
1
Anurag Soni