//準備加載頁面
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注入的。