美文网首页
WKWebView之JS调用OC

WKWebView之JS调用OC

作者: Crazy2015 | 来源:发表于2017-08-11 09:56 被阅读93次
    //准备加载页面
    UIWebViewDelegate - webView:shouldStartLoadWithRequest:navigationType
    WKNavigationDelegate - webView:didStartProvisionalNavigation:
    
    //已开始加载页面,可以在这一步向view中添加一个过渡动画
    UIWebViewDelegate - webViewDidStartLoad:
    WKNavigationDelegate - webView:didCommitNavigation:
    

    以上的主要是Initiating the Navigation

    以下的主要是Responding to Server Actions

    //页面已全部加载,可以在这一步把过渡动画去掉
    UIWebViewDelegate - webViewDidFinishLoad:
    WKNavigationDelegate - webView:didFinishNavigation:
    

    以下的主要是Reacting to Errors

    //加载页面失败
    UIWebViewDelegate - webView:didFailLoadWithError:
    WKNavigationDelegate - webView:didFailNavigation:withError:
    WKNavigationDelegate - webView:didFailProvisionalNavigation:withError:
    

    pragma mark - WKUIDelegate

    // 创建一个新的WebView
    - (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures{
        return [[WKWebView alloc]init];
    }
    // 输入框
    - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler{
        completionHandler(@"http");
    }
    // 确认框
    - (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler{
        completionHandler(YES);
    }
    // 警告框
    - (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
        NSLog(@"%@",message);
        completionHandler();
    }
    
    OC与JS的交互
    @class WKScriptMessage;
    @class WKUserContentController;
    
    /*! A class conforming to the WKScriptMessageHandler protocol provides a
     method for receiving messages from JavaScript running in a webpage.
     */
    @protocol WKScriptMessageHandler <NSObject>
    
    @required
    
    /*! @abstract Invoked when a script message is received from a webpage.
     @param userContentController The user content controller invoking the
     delegate method.
     @param message The script message received.
     */
    - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;
    
    @end
    

    WKScriptMessageHandler其实就是一个协议,它能让网页通过JS把消息发送给OC

    A WKUserContentController object provides a way for JavaScript to post messages to a web view.
    
    The user content controller associated with a web view is specified by its web view configuration.
    
    
    WKUserContentController有两个核心方法,也是它的核心功能。
    
    //: js注入,即向网页中注入我们的js方法,这是一个非常强大的功能,开发中要慎用。
    - (void)addUserScript:(WKUserScript *)userScript;
    
    //:添加供js调用oc的桥梁。这里的name对应WKScriptMessage中的name,多数情况下我们认为它就是方法名。
    - (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name;
    
    
    WKScriptMessage
    
    WKScriptMessage就是js通知oc的数据。其中有两个核心属性用的很多。
    //对应- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name;添加的name。
    @property (nonatomic, readonly, copy) NSString *name; 
    //携带的核心数据。
    @property (nonatomic, readonly, copy) id body;
    
    
    js调用时只需
    
    window.webkit.messageHandlers.<name>.postMessage(<messageBody>)
    
    这里的name就是我们添加的name
    
    JS调用OC

    配置WKUserContentController
    要想使用WKUserContentController为web页面添加桥梁,只需配置到WKWebViewConfiguration即可。

    #pragma mark - get方法
    - (WKWebView *)webView {
        if (_webView == nil) {
            // js配置
            WKUserContentController *userContentController = [[WKUserContentController alloc] init];
            [userContentController addScriptMessageHandler:self name:@"jsCallOC"];
    
            // WKWebView的配置
            WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
            configuration.userContentController = userContentController;
    
            // 显示WKWebView
            _webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration];
            _webView.UIDelegate = self; // 设置WKUIDelegate代理
            [self.view addSubview:_webView];
        }
        return _webView;
    }
    
    实现WKScriptMessageHandler

    在当前页面引入WKScriptMessageHandler,并实现WKScriptMessageHandler协议即可。

    @interface YJBaseVC () <WKScriptMessageHandler>
    
    #pragma mark - WKScriptMessageHandler
    - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
        NSLog(@"方法名:%@", message.name);
        NSLog(@"参数:%@", message.body);
        // 方法名
        NSString *methods = [NSString stringWithFormat:@"%@:", message.name];
        SEL selector = NSSelectorFromString(methods);
        // 调用方法
        if ([self respondsToSelector:selector]) {
            [self performSelector:selector withObject:message.body];
        } else {
            NSLog(@"未实行方法:%@", methods);
        }
    }
    

    window.webkit.messageHandlers.jsCallOC.postMessage(dict);通知oc,jsCallOC这个属性就是前面我们通过WKUserContentController注入的。

    相关文章

      网友评论

          本文标题:WKWebView之JS调用OC

          本文链接:https://www.haomeiwen.com/subject/eiahrxtx.html