没有 WKScriptMessage 的 WKWebView 回调
WKWebView callback without WKScriptMessage
关于在 macOS 上使用 WKWebView
和 objective-c 的信息似乎不多,所以我一直在尝试使用各种 iOS/Swift 示例来说明。问题是我从 JS 到 ObjC 的回调不起作用。即使在 userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
函数处设置的断点也永远不会命中。
显然我在这里漏掉了一步。
我的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];
}
原始代码不起作用的原因有两个。首先是因为 WKWebviewConfiguration
需要自己初始化(WKWebView 不会为你初始化它的配置),其次是 postMessage
必须至少有一个参数。
#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];
}
这是传递参数的方式
- (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];
}
关于在 macOS 上使用 WKWebView
和 objective-c 的信息似乎不多,所以我一直在尝试使用各种 iOS/Swift 示例来说明。问题是我从 JS 到 ObjC 的回调不起作用。即使在 userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
函数处设置的断点也永远不会命中。
显然我在这里漏掉了一步。
我的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];
}
原始代码不起作用的原因有两个。首先是因为 WKWebviewConfiguration
需要自己初始化(WKWebView 不会为你初始化它的配置),其次是 postMessage
必须至少有一个参数。
#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];
}
这是传递参数的方式
- (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];
}