Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WKWebView callback without WKScriptMessage

There does not seem to be much information out there on using WKWebView with objective-c on macOS so I have been trying to make due using various iOS/Swift examples. The problem is that my callback from JS to ObjC does not work. Even the breakpoint set at the userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message function is never hit.

Clearly I am missing a step here.

My AppDelegate.m:

#import <WebKit/WebKit.h>
#import "AppDelegate.h"

@interface AppDelegate () <WKScriptMessageHandler>

@property (weak) IBOutlet NSWindow *window;
@end

@implementation AppDelegate

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

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    WKWebViewConfiguration *config = [WKWebViewConfiguration alloc];
    [[config userContentController] addScriptMessageHandler:self name: @"log"];
    WKWebView *webview = [[WKWebView alloc] initWithFrame:[[_window contentView] frame] configuration:config];
    NSString *htmlStr = @"<!DOCTYPE html><html><body><button type=\"button\" onclick=\"myFunction()\">Click Me!</button><script     type=\"text/javascript\">function myFunction() { window.webkit.messageHandlers.log.postMessage();}</script></body></html>";
    [[_window contentView] addSubview:webview];
    [webview loadHTMLString:htmlStr baseURL:nil];
} 
like image 302
Jlegend Avatar asked Jun 22 '26 11:06

Jlegend


1 Answers

The reason the original code does not work is twofold. First is simply because WKWebviewConfiguration needs to be initialized by itself (WKWebView does not initialize its configuration for you) and second is that postMessage must have at least one argument.

#import <WebKit/WebKit.h>
#import "AppDelegate.h"

@interface AppDelegate () <WKScriptMessageHandler>

@property (weak) IBOutlet NSWindow *window;
@end

@implementation AppDelegate

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

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    [[config userContentController] addScriptMessageHandler:self name: @"log"];
    WKWebView *webview = [[WKWebView alloc] initWithFrame:[[_window contentView] frame] configuration:config];
    NSString *htmlStr = @"<!DOCTYPE html><html><body><button type=\"button\" onclick=\"myFunction()\">Click Me!</button><script type=\"text/javascript\">function myFunction() { window.webkit.messageHandlers.log.postMessage(null); }</script></body></html>";
    [[_window contentView] addSubview:webview];
    [webview loadHTMLString:htmlStr baseURL:nil];
} 

Here is how you would pass an argument

 - (void)userContentController:(WKUserContentController *)userContentController
       didReceiveScriptMessage:(WKScriptMessage *)message {
     if ([message.name isEqualToString:@"log"])
         NSLog(@"%@", message.body);

 }
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    [[config userContentController] addScriptMessageHandler:self name: @"log"];
    WKWebView *webview = [[WKWebView alloc] initWithFrame:[[_window contentView] frame] configuration:config];
    NSString *htmlStr = @"<!DOCTYPE html><html><body><button type=\"button\" onclick=\"myFunction()\">Click Me!</button><script type=\"text/javascript\">function myFunction() { window.webkit.messageHandlers.log.postMessage('clicked'); }</script></body></html>";
    [[_window contentView] addSubview:webview];
    [webview loadHTMLString:htmlStr baseURL:nil];
}
like image 84
Jlegend Avatar answered Jun 25 '26 01:06

Jlegend



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!