An object that displays interactive web content, such as for an in-app browser.

WKWebView属于WebKit.framework框架,Apple在WWDC 2014中随iOS 8和OS X 10.10提出来的,为了解决UIWebView加载速度慢、占用内存大的问题。 使用UIWebView加载网页的时候,内存会无限增长,还有内存泄漏的问题存在。 WebKit中更新的WKWebView控件的新特性与使用方法,很好的解决了UIWebView存在的内存、加载速度等诸多问题。支持到iOS8,相对于UIWebView,WKWebView有很多明显优势:

  • 占用更少的内存
  • Safari相同的JavaScript引擎
  • 拥有高达60FPS滚动刷新率及内置手势
  • html页面和WKWebView交互更方便
  • 提供常用的属性,如加载网页进度的属性estimatedProgress
  • 支持了更多的HTML5特性

UIWebView

WKWebView

所以,使用WkWebview替换UIWebView还是很有必要的。

基本使用

一、导入WebKit.framework框架,并且引入头文件

#import <WebKit/WebKit.h>

二、初始化

// 初始化1
- (instancetype)initWithFrame:(CGRect)frame;

// 初始化2,WKWebViewConfiguration可以用来设置与js交互的相关配置
- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration;

三、WKWebView的使用

1.WKWebView简单使用,直接加载url地址

WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://developer.apple.com/reference/webkit"]]];    
[self.view addSubview:webView];

2.自定义配置,WKWebView里面注册供JS调用的方法

//创建配置
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
//创建UserContentController(提供JavaScript向webView发送消息的方法)
WKUserContentController *userContent = [[WKUserContentController alloc] init];
//添加消息处理,self指代的对象需要遵守WKScriptMessageHandler协议,结束时需要移除
[userContent addScriptMessageHandler:self name:@"NativeMethod"];
//将UserConttentController设置到配置文件
config.userContentController = userContent;
//自定义配置创建WKWebView
WKWebView *webView = [[WKWebView alloc] initWithFrame:[UIScreen mainScreen].bounds configuration:config];
//设置访问的URL
NSURL *url = [NSURL URLWithString:@"https://developer.apple.com/reference/webkit"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
[self.view addSubview:webView];


//实现WKScriptMessageHandler协议方法
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
  // 判断是否是调用原生的
   if ([@"NativeMethod" isEqualToString:message.name]) {
     // 判断message的内容,然后做相应的操作
      if ([@"close" isEqualToString:message.body]) {

      }
   }
}
//将当前ViewController设置为MessageHandler之后需要在当前ViewController销毁前将其移除,否则会造成内存泄漏
- (void)dealloc{
    //WKUserContentController *userContentController
    [userContentController removeScriptMessageHandlerForName:@"NativeMethod"];
}

四、WKWebView主要属性

/*! @abstract A copy of the configuration with which the web view was initialized. */
//只读的配置属性
@property (nonatomic, readonly, copy) WKWebViewConfiguration *configuration;

/*! @abstract The web view's navigation delegate. */
//导航代理
@property (nullable, nonatomic, weak) id <WKNavigationDelegate> navigationDelegate;

/*! @abstract The web view's user interface delegate. */
//用户交互代理
@property (nullable, nonatomic, weak) id <WKUIDelegate> UIDelegate;

/*! @abstract The web view's back-forward list. */
//前进后退列表
@property (nonatomic, readonly, strong) WKBackForwardList *backForwardList;

/*! @abstract The page title.
 @discussion @link WKWebView @/link is key-value observing (KVO) compliant
 for this property.
 */
//网页标题,可以用kvo监听
@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.
 */
//请求的url,可用kvo监听
@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.
 */
//当前是否正在加载网页,可用kvo监听
@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.
 */
//加载进度范围0~1,可用kvo监听
@property (nonatomic, readonly) double estimatedProgress;

/*! @abstract A Boolean value indicating whether all resources on the page
 have been loaded over securely encrypted connections.
 @discussion @link WKWebView @/link is key-value observing (KVO) compliant
 for this property.
 */
//标识页面中的所有资源是否通过安全加密连接来加载,可用kvo监听
@property (nonatomic, readonly) BOOL hasOnlySecureContent;

/*! @abstract A Boolean value indicating whether horizontal swipe gestures
 will trigger back-forward list navigations.
 @discussion The default value is NO.
 */
//是否支持左右的swipe手势是否可以前进、后退
@property (nonatomic) BOOL allowsBackForwardNavigationGestures;

/*! @abstract The custom user agent string or nil if no custom user agent string has been set.
*/
//用户自定义的user agent 没有则为nil
@property (nullable, nonatomic, copy) NSString *customUserAgent API_AVAILABLE(macosx(10.11), ios(9.0));

/*! @abstract A Boolean value indicating whether link preview is allowed for any
 links inside this WKWebView.
 @discussion The default value is YES on Mac and iOS.
 */
//标识不允许链接预览,在iOS上默认为NO
@property (nonatomic) BOOL allowsLinkPreview API_AVAILABLE(macosx(10.11), ios(9.0));

#if TARGET_OS_IPHONE
/*! @abstract The scroll view associated with the web view.
 */
//展示网页内容的scrollview
@property (nonatomic, readonly, strong) UIScrollView *scrollView;
#endif

#if !TARGET_OS_IPHONE
/* @abstract A Boolean value indicating whether magnify gestures will
 change the web view's magnification.
 @discussion It is possible to set the magnification property even if
 allowsMagnification is set to NO.
 The default value is NO.
 */
//是否可以放大,默认为no
@property (nonatomic) BOOL allowsMagnification;

/* @abstract The factor by which the page content is currently scaled.
 @discussion The default value is 1.0.
 */
//放大因子,默认1
@property (nonatomic) CGFloat magnification;

五、WKWebView主要方法

/*! @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 Reloads the current page, performing end-to-end revalidation
 using cache-validating conditionals if possible.
 @result A new navigation representing the reload.
 */
//重新加载原始URL
- (nullable WKNavigation *)reloadFromOrigin;

/*! @abstract Stops loading all resources on the current page.
 */
//停止加载
- (void)stopLoading;

/* @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.
*/
//执行JS代码
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler;

/* @abstract Scales the page content by a specified factor and centers the
 result on a specified point.
 * @param magnification The factor by which to scale the content.
 * @param point The point (in view space) on which to center magnification.
 */
//根据设置的缩放因子来缩放页面,并居中显示结果在指定的点
- (void)setMagnification:(CGFloat)magnification centeredAtPoint:(CGPoint)point;

六、代理方法

1.WKNavigationDelegate

WKNavigationDelegate主要处理一些跳转、加载处理操作,所以WKNavigationDelegate 更加常用。如果实现了代理方法,一定要在decidePolicyForNavigationAction和decidePolicyForNavigationResponse方法中的回调设置允许跳转。

//1.在发送请求之前,决定是否跳转
//WKNavigationActionPolicyCancel 取消跳转
//WKNavigationActionPolicyAllow  允许跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    NSLog(@"1-------在发送请求之前,决定是否跳转  -->%@",navigationAction.request);
    decisionHandler(WKNavigationActionPolicyAllow);
}
//2.页面开始加载时调用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
    NSLog(@"2----页面开始加载时调用");
}
//3.收到响应后,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
    //在收到服务器的响应头,根据response相关信息,决定是否跳转。decisionHandler必须调用,来决定是否跳转,参数WKNavigationActionPolicyCancel取消跳转,WKNavigationActionPolicyAllow允许跳转
    NSLog(@"3-------在收到响应后,决定是否跳转");
    decisionHandler(WKNavigationResponsePolicyAllow);
}
//4.当内容开始返回时调用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
    NSLog(@"4-------当内容开始返回时调用");
}
//5.页面加载完成之后调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
    NSLog(@"5-------页面加载完成之后调用");
}

//6.页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation {
    NSLog(@"6-------页面加载失败时调用");
}
//接收到服务器跳转请求之后调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation {
    NSLog(@"-------接收到服务器跳转请求之后调用");
}
//数据加载发生错误时调用
- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
    NSLog(@"----数据加载发生错误时调用");
}
// 需要响应身份验证时调用 同样在block中需要传入用户身份凭证
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler {
    //用户身份信息
    NSLog(@"----需要响应身份验证时调用 同样在block中需要传入用户身份凭证");
    NSURLCredential *newCred = [NSURLCredential credentialWithUser:@"" password:@"" persistence:NSURLCredentialPersistenceNone];
    // 为 challenge 的发送方提供 credential
    [[challenge sender] useCredential:newCred forAuthenticationChallenge:challenge];
    completionHandler(NSURLSessionAuthChallengeUseCredential,newCred);
}
// 进程被终止时调用
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
    NSLog(@"----------进程被终止时调用");
}

2.WKUIDelegate

WKUIDelegate主要处理JS脚本,确认框,警告框等。

/**
 *  web界面中有弹出警告框时调用
 *  @param webView           实现该代理的webview
 *  @param message           警告框中的内容
 *  @param completionHandler 警告框消失调用
 */
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(void (^)())completionHandler {
    NSLog(@"web界面中有弹出警告框时调用");
}

//创建新的webView时调用的方法
- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures {
    NSLog(@"创建新的webView时调用的方法");
    return webView;
}
//关闭webView时调用的方法
- (void)webViewDidClose:(WKWebView *)webView {
    NSLog(@"关闭webView时调用的方法");
}
//下面这些方法是交互JavaScript的方法
//JavaScript调用confirm方法后回调的方法 confirm是js中的确定框,需要在block中把用户选择的情况传递进去
-(void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler {
    NSLog(@"%@",message);
    completionHandler(YES);
}
//JavaScript调用prompt方法后回调的方法 prompt是js中的输入框 需要在block中把用户输入的信息传入
-(void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
    NSLog(@"%@",prompt);
    completionHandler(@"123");
}
//默认预览元素调用
- (BOOL)webView:(WKWebView *)webView shouldPreviewElement:(WKPreviewElementInfo *)elementInfo {
    NSLog(@"默认预览元素调用");
    return YES;
}
//返回一个视图控制器将导致视图控制器被显示为一个预览。返回nil将WebKit的默认预览的行为。
- (nullable UIViewController *)webView:(WKWebView *)webView previewingViewControllerForElement:(WKPreviewElementInfo *)elementInfo defaultActions:(NSArray<id <WKPreviewActionItem>> *)previewActions {
    NSLog(@"返回一个视图控制器将导致视图控制器被显示为一个预览。返回nil将WebKit的默认预览的行为。");
    return self;
}
//允许应用程序向它创建的视图控制器弹出
- (void)webView:(WKWebView *)webView commitPreviewingViewController:(UIViewController *)previewingViewController {
    NSLog(@"允许应用程序向它创建的视图控制器弹出");
}
// 显示一个文件上传面板。completionhandler完成处理程序调用后打开面板已被撤销。通过选择的网址,如果用户选择确定,否则为零。如果不实现此方法,Web视图将表现为如果用户选择了取消按钮。
- (void)webView:(WKWebView *)webView runOpenPanelWithParameters:(WKOpenPanelParameters *)parameters initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSArray<NSURL *> * _Nullable URLs))completionHandler {
    NSLog(@"显示一个文件上传面板");
}
posted on 2018-10-08 17:11  广坤山货  阅读(397)  评论(0编辑  收藏  举报