An object that displays interactive web content, such as for an in-app browser.html
WKWebView屬於WebKit.framework框架,Apple在WWDC 2014中隨iOS 8和OS X 10.10提出來的,爲了解決UIWebView加載速度慢、佔用內存大的問題。 使用UIWebView加載網頁的時候,內存會無限增加,還有內存泄漏的問題存在。 WebKit中更新的WKWebView控件的新特性與使用方法,很好的解決了UIWebView存在的內存、加載速度等諸多問題。支持到iOS8,相對於UIWebView,WKWebView有不少明顯優點:java
UIWebViewios
WKWebViewweb
因此,使用WkWebview替換UIWebView仍是頗有必要的。macos
WebKit.framework
框架,而且引入頭文件#import <WebKit/WebKit.h>
// 初始化1 - (instancetype)initWithFrame:(CGRect)frame; // 初始化2,WKWebViewConfiguration能夠用來設置與js交互的相關配置 - (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration;
WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.bounds]; [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://developer.apple.com/reference/webkit"]]]; [self.view addSubview:webView];
//建立配置 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"]; }
/*! @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;
/*! @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;
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(@"----------進程被終止時調用"); }
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(@"顯示一個文件上傳面板"); }