//准备加载页面
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注入的。