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 <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注入的。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容