背景介绍
从iOS8开始,推出WebKit,用WKWebView,替代原有的UIWebView。WebKit和WKWebView是今后研究的重点。
WKWebView类图
WKWebView
- 加载url(主要是远程,本地也可以)指定的网页,NSURLRequest -> NSURL -> NSString
/*! @abstract Navigates to a requested URL.
@param request The request specifying the URL to which to navigate.
@result A new navigation for the given request.
*/
- (nullable WKNavigation *)loadRequest:(NSURLRequest *)request; ```
* 跳转到指定页,非正常跳转
/*! @abstract Navigates to an item from the back-forward list and sets it
as the current item.
@param item The item to which to navigate. Must be one of the items in the
web view's back-forward list.
@result A new navigation to the requested item, or nil if it is already
the current item or is not part of the web view's back-forward list.
@seealso backForwardList
*/
- (nullable WKNavigation *)goToBackForwardListItem:(WKBackForwardListItem *)item;
* 几个可以通过KVO进行监控的属性
/*! @abstract The page title.
@discussion @link WKWebView @/link is key-value observing (KVO) compliant
for this property.
*/
@property (nullable, nonatomic, readonly, copy) NSString *title;
/*! @abstract The active URL.
@discussion This is the URL that should be reflected in the user
interface.
@link WKWebView @/link is key-value observing (KVO) compliant for this
property.
*/
@property (nullable, nonatomic, readonly, copy) NSURL *URL;
/*! @abstract A Boolean value indicating whether the view is currently
loading content.
@discussion @link WKWebView @/link is key-value observing (KVO) compliant
for this property.
*/
@property (nonatomic, readonly, getter=isLoading) BOOL loading;
/*! @abstract An estimate of what fraction of the current navigation has been completed.
@discussion This value ranges from 0.0 to 1.0 based on the total number of
bytes expected to be received, including the main document and all of its
potential subresources. After a navigation completes, the value remains at 1.0
until a new navigation starts, at which point it is reset to 0.0.
@link WKWebView @/link is key-value observing (KVO) compliant for this
property.
*/
@property (nonatomic, readonly) double estimatedProgress;
/*! @abstract A Boolean value indicating whether there is a back item in
the back-forward list that can be navigated to.
@discussion @link WKWebView @/link is key-value observing (KVO) compliant
for this property.
@seealso backForwardList.
*/
@property (nonatomic, readonly) BOOL canGoBack;
/*! @abstract A Boolean value indicating whether there is a forward item in
the back-forward list that can be navigated to.
@discussion @link WKWebView @/link is key-value observing (KVO) compliant
for this property.
@seealso backForwardList.
*/
@property (nonatomic, readonly) BOOL canGoForward;
* 页面跳转动作
/*! @abstract Navigates to the back item in the back-forward list.
@result A new navigation to the requested item, or nil if there is no back
item in the back-forward list.
*/
- (nullable WKNavigation *)goBack;
/*! @abstract Navigates to the forward item in the back-forward list.
@result A new navigation to the requested item, or nil if there is no
forward item in the back-forward list.
*/
- (nullable WKNavigation *)goForward;
/*! @abstract Reloads the current page.
@result A new navigation representing the reload.
*/
- (nullable WKNavigation *)reload;
/*! @abstract Stops loading all resources on the current page.
*/
- (void)stopLoading;
* 执行JS代码
/* @abstract Evaluates the given JavaScript string.
@param javaScriptString The JavaScript string to evaluate.
@param completionHandler A block to invoke when script evaluation completes or fails.
@discussion The completionHandler is passed the result of the script evaluation or an error.
*/
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ __nullable)(__nullable id, NSError * __nullable error))completionHandler;
* 手势开关,默认关闭
/*! @abstract A Boolean value indicating whether horizontal swipe gestures
will trigger back-forward list navigations.
@discussion The default value is NO.
*/
@property (nonatomic) BOOL allowsBackForwardNavigationGestures;
## WKNavigationDelegate 协议
参考文章:[WebKit(WKNavigationDelegate)](http://blog.csdn.net/y550918116j/article/details/50148489)
* 页面加载状态回调
pragma mark 页面开始加载时调用
/*! @abstract Invoked when a main frame navigation starts.
@param webView The web view invoking the delegate method.
@param navigation The navigation.
*/
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation;
pragma mark 当内容开始返回时调用
/*! @abstract Invoked when content starts arriving for the main frame.
@param webView The web view invoking the delegate method.
@param navigation The navigation.
*/
- (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation;
pragma mark 页面加载完成之后调用
/*! @abstract Invoked when a main frame navigation completes.
@param webView The web view invoking the delegate method.
@param navigation The navigation.
*/
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation;
pragma mark 页面加载失败时调用
/*! @abstract Invoked when an error occurs while starting to load data for
the main frame.
@param webView The web view invoking the delegate method.
@param navigation The navigation.
@param error The error that occurred.
*/
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error;
* 页面跳转
pragma mark 在发送请求之前,决定是否跳转
/*! @abstract Decides whether to allow or cancel a navigation.
@param webView The web view invoking the delegate method.
@param navigationAction Descriptive information about the action
triggering the navigation request.
@param decisionHandler The decision handler to call to allow or cancel the
navigation. The argument is one of the constants of the enumerated type WKNavigationActionPolicy.
@discussion If you do not implement this method, the web view will load the request or, if appropriate, forward it to another application.
*/
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;
pragma mark 身份验证
/*! @abstract Invoked when the web view needs to respond to an authentication challenge.
@param webView The web view that received the authentication challenge.
@param challenge The authentication challenge.
@param completionHandler The completion handler you must invoke to respond to the challenge. The
disposition argument is one of the constants of the enumerated type
NSURLSessionAuthChallengeDisposition. When disposition is NSURLSessionAuthChallengeUseCredential,
the credential argument is the credential to use, or nil to indicate continuing without a
credential.
@discussion If you do not implement this method, the web view will respond to the authentication challenge with the NSURLSessionAuthChallengeRejectProtectionSpace disposition.
*/
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *__nullable credential))completionHandler;
pragma mark 在收到响应后,决定是否跳转
/*! @abstract Decides whether to allow or cancel a navigation after its
response is known.
@param webView The web view invoking the delegate method.
@param navigationResponse Descriptive information about the navigation
response.
@param decisionHandler The decision handler to call to allow or cancel the
navigation. The argument is one of the constants of the enumerated type WKNavigationResponsePolicy.
@discussion If you do not implement this method, the web view will allow the response, if the web view can show it.
*/
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;
pragma mark 接收到服务器跳转请求之后调用
/*! @abstract Invoked when a server redirect is received for the main
frame.
@param webView The web view invoking the delegate method.
@param navigation The navigation.
*/
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation;
pragma mark WKNavigation导航错误
/*! @abstract Invoked when an error occurs during a committed main frame
navigation.
@param webView The web view invoking the delegate method.
@param navigation The navigation.
@param error The error that occurred.
*/
- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error;
pragma mark WKWebView终止
/*! @abstract Invoked when the web view's web content process is terminated.
@param webView The web view whose underlying web content process was terminated.
*/
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView NS_AVAILABLE(10_11, 9_0);
## WKUIDelegate协议
* 创建和关闭新的WKWebView
pragma mark 新建webView
/*! @abstract Creates a new web view.
@param webView The web view invoking the delegate method.
@param configuration The configuration to use when creating the new web
view.
@param navigationAction The navigation action causing the new web view to
be created.
@param windowFeatures Window features requested by the webpage.
@result A new web view or nil.
@discussion The web view returned must be created with the specified configuration. WebKit will load the request in the returned web view.
If you do not implement this method, the web view will cancel the navigation.
*/
- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures;
pragma mark 关闭webView
/*! @abstract Notifies your app that the DOM window object's close() method completed successfully.
@param webView The web view invoking the delegate method.
@discussion Your app should remove the web view from the view hierarchy and update
the UI as needed, such as by closing the containing browser tab or window.
*/
- (void)webViewDidClose:(WKWebView *)webView NS_AVAILABLE(10_11, 9_0);
* 对话框
[参考文章](https://github.com/937447974/Blog/blob/master/IOS/Core%20Services%20Layer/WebKit/WebKit(WKUIDelegate).md)
pragma mark alert弹出框
/*! @abstract Displays a JavaScript alert panel.
@param webView The web view invoking the delegate method.
@param message The message to display.
@param frame Information about the frame whose JavaScript initiated this
call.
@param completionHandler The completion handler to call after the alert
panel has been dismissed.
@discussion For user security, your app should call attention to the fact
that a specific website controls the content in this panel. A simple forumla
for identifying the controlling website is frame.request.URL.host.
The panel should have a single OK button.
If you do not implement this method, the web view will behave as if the user selected the OK button.
*/
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler;
pragma mark Confirm选择框
/*! @abstract Displays a JavaScript confirm panel.
@param webView The web view invoking the delegate method.
@param message The message to display.
@param frame Information about the frame whose JavaScript initiated this call.
@param completionHandler The completion handler to call after the confirm
panel has been dismissed. Pass YES if the user chose OK, NO if the user
chose Cancel.
@discussion For user security, your app should call attention to the fact
that a specific website controls the content in this panel. A simple forumla
for identifying the controlling website is frame.request.URL.host.
The panel should have two buttons, such as OK and Cancel.
If you do not implement this method, the web view will behave as if the user selected the Cancel button.
*/
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler;
pragma mark TextInput输入框
/*! @abstract Displays a JavaScript text input panel.
@param webView The web view invoking the delegate method.
@param message The message to display.
@param defaultText The initial text to display in the text entry field.
@param frame Information about the frame whose JavaScript initiated this call.
@param completionHandler The completion handler to call after the text
input panel has been dismissed. Pass the entered text if the user chose
OK, otherwise nil.
@discussion For user security, your app should call attention to the fact
that a specific website controls the content in this panel. A simple forumla
for identifying the controlling website is frame.request.URL.host.
The panel should have two buttons, such as OK and Cancel, and a field in
which to enter text.
If you do not implement this method, the web view will behave as if the user selected the Cancel button.
*/
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler;
## WKUserContentController
这个类专门用来和JS进行双向通讯,这是相对于UIWebView来说新增的部分。[参考文章](https://github.com/937447974/Blog/blob/master/IOS/Core%20Services%20Layer/WebKit/WebKit(WKScriptMessageHandler).md)
### Native -》JS
通过本地注入的方式实现Native到JS的通信
/*! @abstract The user scripts associated with this user content
controller.
*/
@property (nonatomic, readonly, copy) NSArray<WKUserScript *> *userScripts;
/*! @abstract Adds a user script.
@param userScript The user script to add.
*/
- (void)addUserScript:(WKUserScript *)userScript;
/*! @abstract Removes all associated user scripts.
*/
- (void)removeAllUserScripts;
#### WKUserScript
/*! @abstract Returns an initialized user script that can be added to a @link WKUserContentController @/link.
@param source The script source.
@param injectionTime When the script should be injected.
@param forMainFrameOnly Whether the script should be injected into all frames or just the main frame.
*/
- (instancetype)initWithSource:(NSString *)source injectionTime:(WKUserScriptInjectionTime)injectionTime forMainFrameOnly:(BOOL)forMainFrameOnly;
// 注入时机
typedef NS_ENUM(NSInteger, WKUserScriptInjectionTime) {
WKUserScriptInjectionTimeAtDocumentStart,
WKUserScriptInjectionTimeAtDocumentEnd
} NS_ENUM_AVAILABLE(10_10, 8_0);
### JS -》Native
通过消息发送,接收的方式实现JS到Native的通信
/*! @abstract Adds a script message handler.
@param scriptMessageHandler The message handler to add.
@param name The name of the message handler.
@discussion Adding a scriptMessageHandler adds a function
window.webkit.messageHandlers.<name>.postMessage(<messageBody>) for all
frames.
*/
- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name;
/*! @abstract Removes a script message handler.
@param name The name of the message handler to remove.
*/
- (void)removeScriptMessageHandlerForName:(NSString *)name;
#### WKScriptMessageHandler协议
@required
// 接收来自JS的消息,做相应的处理
/*! @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;
##### WKScriptMessage
// 一般用字典,可以放足够多的信息
/*! @abstract The body of the message.
@discussion Allowed types are NSNumber, NSString, NSDate, NSArray,
NSDictionary, and NSNull.
*/
@property (nonatomic, readonly, copy) id body;
/*! @abstract The web view sending the message. */
@property (nullable, nonatomic, readonly, weak) WKWebView *webView;
/*! @abstract The frame sending the message. */
@property (nonatomic, readonly, copy) WKFrameInfo *frameInfo;
// 消息标识符,区分不同的消息
/*! @abstract The name of the message handler to which the message is sent.
*/
@property (nonatomic, readonly, copy) NSString *name;
## 拦截URL的Native和H5的交互(兼容UIWebView)
### Native -》JS
WKWebView的成员函数
/* @abstract Evaluates the given JavaScript string.
@param javaScriptString The JavaScript string to evaluate.
@param completionHandler A block to invoke when script evaluation completes or fails.
@discussion The completionHandler is passed the result of the script evaluation or an error.
*/
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ __nullable)(__nullable id, NSError * __nullable error))completionHandler;
### JS -》Native
WKNavigationDelegate的代理方法
/*! @abstract Decides whether to allow or cancel a navigation.
@param webView The web view invoking the delegate method.
@param navigationAction Descriptive information about the action
triggering the navigation request.
@param decisionHandler The decision handler to call to allow or cancel the
navigation. The argument is one of the constants of the enumerated type WKNavigationActionPolicy.
@discussion If you do not implement this method, the web view will load the request or, if appropriate, forward it to another application.
*/
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;
#### WKNavigationResponsePolicy
/*! @enum WKNavigationResponsePolicy
@abstract The policy to pass back to the decision handler from the webView:decidePolicyForNavigationResponse:decisionHandler: method.
@constant WKNavigationResponsePolicyCancel Cancel the navigation.
@constant WKNavigationResponsePolicyAllow Allow the navigation to continue.
*/
typedef NS_ENUM(NSInteger, WKNavigationResponsePolicy) {
WKNavigationResponsePolicyCancel,
WKNavigationResponsePolicyAllow,
} NS_ENUM_AVAILABLE(10_10, 8_0);
#### WKNavigationAction
/*! @abstract The frame requesting the navigation.
*/
@property (nonatomic, readonly, copy) WKFrameInfo *sourceFrame;
/*! @abstract The target frame, or nil if this is a new window navigation.
*/
@property (nullable, nonatomic, readonly, copy) WKFrameInfo *targetFrame;
/*! @abstract The type of action that triggered the navigation.
@discussion The value is one of the constants of the enumerated type WKNavigationType.
*/
@property (nonatomic, readonly) WKNavigationType navigationType;
/*! @abstract The navigation's request.
*/
@property (nonatomic, readonly, copy) NSURLRequest *request;
##### WKNavigationType
/*! @enum WKNavigationType
@abstract The type of action triggering a navigation.
@constant WKNavigationTypeLinkActivated A link with an href attribute was activated by the user.
@constant WKNavigationTypeFormSubmitted A form was submitted.
@constant WKNavigationTypeBackForward An item from the back-forward list was requested.
@constant WKNavigationTypeReload The webpage was reloaded.
@constant WKNavigationTypeFormResubmitted A form was resubmitted (for example by going back, going forward, or reloading).
@constant WKNavigationTypeOther Navigation is taking place for some other reason.
*/
typedef NS_ENUM(NSInteger, WKNavigationType) {
WKNavigationTypeLinkActivated,
WKNavigationTypeFormSubmitted,
WKNavigationTypeBackForward,
WKNavigationTypeReload,
WKNavigationTypeFormResubmitted,
WKNavigationTypeOther = -1,
} NS_ENUM_AVAILABLE(10_10, 8_0);
##### WKFrameInfo
/*! @abstract A Boolean value indicating whether the frame is the main frame
or a subframe.
*/
@property (nonatomic, readonly, getter=isMainFrame) BOOL mainFrame;
// 这里的url可以区分不同的请求
/*! @abstract The frame's current request.
*/
@property (nonatomic, readonly, copy) NSURLRequest *request;
/*! @abstract The frame's current security origin.
*/
@property (nonatomic, readonly) WKSecurityOrigin *securityOrigin NS_AVAILABLE(10_11, 9_0);
## 参考文章
* [WKWebView](http://nshipster.cn/wkwebkit/)
* [使用WKWebView替换UIWebView](http://www.jianshu.com/p/6ba2507445e4)
* [iOS 8 WebKit框架概览(上)](http://www.cocoachina.com/ios/20150203/11089.html)
[iOS 8 WebKit框架概览(下)](http://www.cocoachina.com/ios/20150205/11108.html)
* [Introducing the Modern WebKit API](https://developer.apple.com/videos/play/wwdc2014/206/)
* **[WebViewJavascriptBridge](https://github.com/marcuswestin/WebViewJavascriptBridge)**
* [自己动手打造基于 WKWebView 的混合开发框架(一)——WKWebView 上手](https://lvwenhan.com/ios/460.html)
* [自己动手打造基于 WKWebView 的混合开发框架(二)——js 向 Native 一句话传值并反射出 Swift 对象执行指定函数](https://lvwenhan.com/ios/461.html)
* [自己动手打造基于 WKWebView 的混合开发框架(三)——设计插件协议以兼容 Cordova](https://lvwenhan.com/ios/462.html)