WKWebView之JS调用OC

//准备加载页面
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 

@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 )scriptMessageHandler name:(NSString *)name;

WKScriptMessage

WKScriptMessage就是js通知oc的数据。其中有两个核心属性用的很多。
//对应- (void)addScriptMessageHandler:(id )scriptMessageHandler name:(NSString *)name;添加的name。
@property (nonatomic, readonly, copy) NSString *name; 
//携带的核心数据。
@property (nonatomic, readonly, copy) id body;

js调用时只需

window.webkit.messageHandlers..postMessage()

这里的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 () 

#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)