WkWebKit - 加载页面上的javascript发现window.webkit未定义

Bri*_*n B 9 javascript webkit ios wkwebview xcode7

我正在尝试使用WkWebKit在应用程序和页面之间来回交谈.我可以使用WkWebView evaluateJavascript方法让javaScript执行得很好,但是当我尝试在JavaScript页面上执行window.webkit.messageHandlers.myHandler.postMessage('hello world!')时,我发现window.webkit没有定义.

奇怪......我正在ios 8.4的iPad模拟器中运行.我认为这可以在原版8中使用,不是吗?

我找不到其他任何关于此的帖子,所以也许我做错了什么?

我甚至将我的Safari Developer连接到模拟器的浏览器,在控制台中我试着看看window.webkit是什么,当然,它不存在.

请注意,我添加了一个初始脚本,以便在页面加载时运行(我在javascript编辑器中看到了这一点 - 记录了消息).我还添加了一个脚本消息处理程序......

[编辑:在这里添加更多代码详细信息] 这是我的代码:

- (void)viewDidLoad {
  [super viewDidLoad];
  // Do any additional setup after loading the view, typically from a nib.
  NSLog(@"main view Controller viewDidLoad called...");

// if we are running on an OLD ios (pre v8) WKWebView will not exist.  So don't create it if it doesn't exist...
if (NSClassFromString(@"WKWebView")) {
    // WKWebView cannot be dragged onto storyboard, so have to create it manually here.
    // We have a "ContainerView" called _webContainer that this browser view will live inside
    // First we create a web view configuration object...
    WKWebViewConfiguration *wbConfig = [WKWebViewConfiguration alloc];
    wbConfig.mediaPlaybackAllowsAirPlay = true;
    wbConfig.mediaPlaybackRequiresUserAction = false; 
    // inject some Javascript into our page before it even loads...
    NSString *scriptSource = @"console.log('Hi from the iOS app hosting this page...'); window.hostedByWkWebView=true;";
    WKUserScript *userScript = [[WKUserScript alloc]
                                initWithSource:scriptSource
                                injectionTime:WKUserScriptInjectionTimeAtDocumentStart
                                forMainFrameOnly:YES];

    [wbConfig.userContentController addUserScript:userScript];
    [wbConfig.userContentController addScriptMessageHandler:self name:@"myHandler"]; // javascript to use this would be: window.webkit.messageHandlers.myHandler.postMessage


    // Ok, the config is created, now create the WkWebView instance, passing in this config...
    _webView = [[WKWebView alloc] initWithFrame: [_webContainer bounds] configuration:wbConfig];
    _webView.autoresizesSubviews = true;
    _webView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
    _webView.navigationDelegate = self;

    // Add the web view to the container view, and tell the container to automatically resize its subviews, height and width.
    [_webContainer addSubview:_webView];
    _webContainer.autoresizesSubviews = true;
    _webContainer.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;

    // Set the URL for the webview and navigate there...
    NSString *fullURL = @"https://myurlgoeshere.com";

    NSURL *url = [NSURL URLWithString:fullURL];
    NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];

    [_webView loadRequest:requestObj];
}
else {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Cannot create Web View" message:@"The web view used requires iOS 8 or higher.  Sorry." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"", nil];
    [alert show];
}

//...
Run Code Online (Sandbox Code Playgroud)

小智 29

我解决它,问题是,如果你设定userContentController一个新的目标,那userContentControllerWKScriptMessageHandler旨意无法正确在苹果的内部代码注册:

WKUserContentController *userContentController = [WKUserContentController new];
userContentController.addScriptMessageHandler(self, name: "jockey")
userContentController.addScriptMessageHandler(self, name: "observe")
webView.configuration.userContentController = userContentController
Run Code Online (Sandbox Code Playgroud)

通过使用已经userContentController由Apple 实例化修复:

webView.configuration.userContentController.addScriptMessageHandler(self, name: "jockey")
webView.configuration.userContentController.addScriptMessageHandler(self, name: "observe")
Run Code Online (Sandbox Code Playgroud)

  • 你拯救了我的下午……和那个摔跤了一下。谢谢你!;) (2认同)
  • 这是正确的答案并解决了我的问题.知道为什么我们必须使用现有的而不是创建一个新的吗?当我们创建一个新的并设置它时,例如self.wkWebView.configuration.userContentController = userContentController; - 新的一个被忽略了吗?该物业不是只读的. (2认同)
  • 哇,经过一个小时的代码努力,我找到了这个答案。为什么呢?如果有可用的设置器,为什么我们不能使用定制的设置器?WKWebView上的API设计有点差。 (2认同)

sof*_*are 7

window.webkit命名空间仅在带有脚本消息处理程序的webview中显示。确保已调用WKUserContentController的addScriptMessageHandler方法。


Dav*_*son 6

我遇到了这个问题,因为我遇到了同样的问题,这就是我使用自定义CustomContentController( 的子类WKUserContentController)实例解决它的方法。

let userContentController = CustomContentController()
let webViewConfiguration = WKWebViewConfiguration()
webViewConfiguration.userContentController = userContentController
webView = WKWebView(frame: .zero, configuration: webViewConfiguration)
Run Code Online (Sandbox Code Playgroud)

在我的情况下,它是调用该方法CustomContentController的子类,但我认为这并不重要。WKUserContentControlleradd(_ scriptMessageHandler: WKScriptMessageHandler, name: String)

我相信WKUserContentController必须在 WKWebView 初始化WKWebViewConfiguration 之前实例化并应用到 aWKWebView(frame: .zero, configuration: webViewConfiguration)

如果 WKWebView 已创建,然后您尝试更改WKWebViewConfiguration您将遇到window.webkit在 JSContext 中不可用。