日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

iOS中WebKit框架应用与解析

發布時間:2024/7/23 编程问答 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iOS中WebKit框架应用与解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、引言

????? ? 在iOS8之前,在應用中嵌入網頁通常需要使用UIWebView這樣一個類,這個類通過URL或者HTML文件來加載網頁視圖,功能十分有限,只能作為輔助嵌入原生應用程序中。雖然UIWebView也可以做原生與JavaScript交互的相關處理,然而也有很大的局限性,JavaScript要調用原生方法通常需要約定好協議之后通過Request來傳遞。WebKit框架中添加了一些原生與JavaScript交互的方法,增強了網頁視圖與原生的交互能力。并且WebKit框架中采用導航堆棧的模型來管理網頁的跳轉,開發者也可以更加容易的控制和管理網頁的渲染。關于UIWebView的相關使用,在前面的博客中有詳細介紹,地址如下。

二、WebKit框架概覽

????? ? WebKit框架中涉及的類很多,框架的設計十分面向對象和模塊化,開發者在使用時可以輕松的寫出結構清晰的代碼。在進行使用前,我們首先應該清楚整個框架的結構和開發思路,下面一張腦圖中基本列出了WebKit框架中所涉及到的所有重要的類以及他們之間的相互關系:

如上圖所示,WebKit框架中最核心的類應該屬于WKWebView了,這個類專門用來渲染網頁視圖,其他類和協議都將基于它和服務于它。

WKWebView:網頁的渲染與展示,通過WKWebViewConfiguration可以進行配置。

WKWebViewConfiguration:這個類專門用來配置WKWebView。

WKPreference:這個類用來進行M相關設置。

WKProcessPool:這個類用來配置進程池,與網頁視圖的資源共享有關。

WKUserContentController:這個類主要用來做native與JavaScript的交互管理。

WKUserScript:用于進行JavaScript注入。

WKScriptMessageHandler:這個類專門用來處理JavaScript調用native的方法。

WKNavigationDelegate:網頁跳轉間的導航管理協議,這個協議可以監聽網頁的活動。

WKNavigationAction:網頁某個活動的示例化對象。

WKUIDelegate:用于交互處理JavaScript中的一些彈出框。

WKBackForwardList:堆棧管理的網頁列表。

WKBackForwardListItem:每個網頁節點對象。

三、使用WKWebViewConfiguration對WebView進行配置

????? ? 使用下面的代碼可以創建一個WKWebView視圖,創建WebView視圖時,需要使用WKWebViewConfiguration來進行配置:

WKWebView * WK;WKWebViewConfiguration * config = [[WKWebViewConfiguration alloc]init];WK = [[WKWebView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height-40) configuration:config];[WK loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];

WKWebViewConfiguration中可以進行配置的方法和屬性如下:

//設置進程池WKProcessPool * pool = [[WKProcessPool alloc]init];config.processPool = pool;

WKProcessPool類中沒有暴露任何屬性和方法,配置為同一個進程池的WebView會共享數據,例如Cookie、用戶憑證等,開發者可以通過編寫管理類來分配不同維度的WebView在不同進程池中。

//進行偏好設置WKPreferences * preference = [[WKPreferences alloc]init];//最小字體大小 當將javaScriptEnabled屬性設置為NO時,可以看到明顯的效果preference.minimumFontSize = 0;//設置是否支持javaScript 默認是支持的preference.javaScriptEnabled = YES;//設置是否允許不經過用戶交互由javaScript自動打開窗口preference.javaScriptCanOpenWindowsAutomatically = YES;config.preferences = preference;

WKPerference實例為WebView提供一個偏好設置。

//設置內容交互控制器 用于處理JavaScript與native交互WKUserContentController * userController = [[WKUserContentController alloc]init];//設置處理代理并且注冊要被js調用的方法名稱[userController addScriptMessageHandler:self name:@"name"];//js注入,注入一個測試方法。NSString *javaScriptSource = @"function userFunc(){window.webkit.messageHandlers.name.postMessage( {\"name\":\"HS\"})}";WKUserScript *userScript = [[WKUserScript alloc] initWithSource:javaScriptSource injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES];// forMainFrameOnly:NO(全局窗口),yes(只限主窗口)[userController addUserScript:userScript];config.userContentController = userController;

WKUserContentController專門用來管理native與JavaScript的交互行為,addScriptMessageHandler:name:方法來注冊要被js調用的方法名稱,之后再JavaScript中使用window.webkit.messageHandlers.name.postMessage()方法來像native發送消息,支持OC中字典,數組,NSNumber等原生數據類型,JavaScript代碼中的name要和上面注冊的相同。在native代理的回調方法中,會獲取到JavaScript傳遞進來的消息,如下:

-(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{//這里可以獲取到JavaScript傳遞進來的消息 }

WKScriptMessage類是JavaScript傳遞的對象實例,其中屬性如下:

//傳遞的消息主體 @property (nonatomic, readonly, copy) id body; //傳遞消息的WebView @property (nullable, nonatomic, readonly, weak) WKWebView *webView; //傳遞消息的WebView當前頁面對象 @property (nonatomic, readonly, copy) WKFrameInfo *frameInfo; //消息名稱 @property (nonatomic, readonly, copy) NSString *name;

WKUserContentController實例的addUserScript:用于注入JavaScript代碼,后面會專門介紹。

//設置數據存儲storeconfig.websiteDataStore = [WKWebsiteDataStore defaultDataStore];

WebKit框架采用其本身的緩存框架,WKWebsiteDataStore類用來處理數據的存儲,其中屬性和方法如下:

@interface WKWebsiteDataStore : NSObject //獲取默認的存儲器 此存儲器為持久性的會被寫入磁盤 + (WKWebsiteDataStore *)defaultDataStore; //獲取一個臨時的存儲器 + (WKWebsiteDataStore *)nonPersistentDataStore; //存儲器是否是臨時的 @property (nonatomic, readonly, getter=isPersistent) BOOL persistent; //所有可以存儲的類型 + (NSSet<NSString *> *)allWebsiteDataTypes; @end //設置是否將網頁內容全部加載到內存后再渲染config.suppressesIncrementalRendering = NO;//設置HTML5視頻是否允許網頁播放 設置為NO則會使用本地播放器config.allowsInlineMediaPlayback = YES;//設置是否允許ariPlay播放config.allowsAirPlayForMediaPlayback = YES;//設置視頻是否需要用戶手動播放 設置為NO則會允許自動播放config.requiresUserActionForMediaPlayback = NO;//設置是否允許畫中畫技術 在特定設備上有效config.allowsPictureInPictureMediaPlayback = YES;//設置選擇模式 是按字符選擇 還是按模塊選擇/*typedef NS_ENUM(NSInteger, WKSelectionGranularity) {//按模塊選擇WKSelectionGranularityDynamic,//按字符選擇WKSelectionGranularityCharacter,} NS_ENUM_AVAILABLE_IOS(8_0);*/config.selectionGranularity = WKSelectionGranularityCharacter;//設置請求的User-Agent信息中應用程序名稱 iOS9后可用config.applicationNameForUserAgent = @"HS";

四、WKWebView中的屬性和方法解析

??下面列舉了WKWebView中常用的屬性和方法。

//設置導航代理 @property (nullable, nonatomic, weak) id <WKNavigationDelegate> navigationDelegate; //設置UI代理 @property (nullable, nonatomic, weak) id <WKUIDelegate> UIDelegate; //導航列表 @property (nonatomic, readonly, strong) WKBackForwardList *backForwardList; //通過url加載網頁視圖 - (nullable WKNavigation *)loadRequest:(NSURLRequest *)request; //通過文件加載網頁視圖 - (nullable WKNavigation *)loadFileURL:(NSURL *)URL allowingReadAccessToURL:(NSURL *)readAccessURL NS_AVAILABLE(10_11, 9_0); //通過HTML字符串加載網頁視圖 - (nullable WKNavigation *)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL; //通過data數據加載網頁視圖 - (nullable WKNavigation *)loadData:(NSData *)data MIMEType:(NSString *)MIMEType characterEncodingName:(NSString *)characterEncodingName baseURL:(NSURL *)baseURL NS_AVAILABLE(10_11, 9_0); //渲染導航列表中的某個網頁節點 - (nullable WKNavigation *)goToBackForwardListItem:(WKBackForwardListItem *)item; //網頁標題 @property (nullable, nonatomic, readonly, copy) NSString *title; //網頁的url @property (nullable, nonatomic, readonly, copy) NSURL *URL; //網頁是否正在加載中 @property (nonatomic, readonly, getter=isLoading) BOOL loading; //加載進度 可以監聽這個屬性的值配合UIProgressView來設計進度條 @property (nonatomic, readonly) double estimatedProgress; //是否全部是安全連接 @property (nonatomic, readonly) BOOL hasOnlySecureContent; //證書列表 @property (nonatomic, readonly, copy) NSArray *certificateChain; //是否可以回退 @property (nonatomic, readonly) BOOL canGoBack; //是否可以前進 @property (nonatomic, readonly) BOOL canGoForward; //回退網頁 - (nullable WKNavigation *)goBack; //前進網頁 - (nullable WKNavigation *)goForward; //刷新網頁 - (nullable WKNavigation *)reload; //忽略緩存的刷新 - (nullable WKNavigation *)reloadFromOrigin; //停止加載 - (void)stopLoading; //執行JavaScript代碼 - (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ __nullable)(__nullable id, NSError * __nullable error))completionHandler; //是否允許右滑返回手勢 @property (nonatomic) BOOL allowsBackForwardNavigationGestures;

WKBackForwardList類為導航管理的網頁列表類,其中屬性方法意義如下:

@interface WKBackForwardList : NSObject //當前所在的網頁節點 @property (nullable, nonatomic, readonly, strong) WKBackForwardListItem *currentItem; //前進的一個網頁節點 @property (nullable, nonatomic, readonly, strong) WKBackForwardListItem *forwardItem; //回退的一個網頁節點 @property (nullable, nonatomic, readonly, strong) WKBackForwardListItem *backItem; //獲取某個index的網頁節點 - (nullable WKBackForwardListItem *)itemAtIndex:(NSInteger)index; //獲取回退的節點數組 @property (nonatomic, readonly, copy) NSArray<WKBackForwardListItem *> *backList; //獲取前進的節點數組 @property (nonatomic, readonly, copy) NSArray<WKBackForwardListItem *> *forwardList; @end

在WebKit中,網頁節點被抽象成為了WKBackForwardListItem類,這個類中封裝的屬性如下:

@interface WKBackForwardListItem : NSObject //當前節點的URL @property (readonly, copy) NSURL *URL; //當前節點的標題 @property (nullable, readonly, copy) NSString *title; //創建此WebView的初始URL @property (readonly, copy) NSURL *initialURL;

五、關于native與JavaScript交互

?WebKit中的native與JavaScript的交互主要有4類。

1.JavaScript調用native方法

???這種方式是由WKUserContentController注冊,并在代理方法中實現的。

2.native調用JavaScript方法

???這種方式通過WKWebView直接調用evaluteJavaScript:completionHandler:方法來實現。

3.將JavaScript代碼注入

?這種方式可以在網頁中注入一些自定義的JavaScript代碼,也可以注入自定義的方法,再使用evaluteJavaScript:completionHandler:來調用方法。JavaScript代碼的注入也是通過WKUserContentController來完成的,使用addUserScript:方法來注入JavaScript,其中需要通過WKUserScript類來生成要注入的對象,這個類使用如下方法來進行實例化:

/* source為要注入的js代碼 WKUserScriptInjectionTime設置注入的時機 forMainFrameOnly參數設置是否只在主頁面注入 typedef NS_ENUM(NSInteger, WKUserScriptInjectionTime) {//原js代碼運行前注入WKUserScriptInjectionTimeAtDocumentStart,//原js代碼運行后注入WKUserScriptInjectionTimeAtDocumentEnd } NS_ENUM_AVAILABLE(10_10, 8_0);*/ - (instancetype)initWithSource:(NSString *)source injectionTime:(WKUserScriptInjectionTime)injectionTime forMainFrameOnly:(BOOL)forMainFrameOnly;

4.通過WKUIDelegate來交互

???這種方式主要用于相應JavaScript中的彈出框,后面會詳細介紹這個協議。

六、WKNavagationDelegate中方法解析

? ?WKNavagationDelegate協議重要有兩個作用,監聽頁面渲染流程與控制頁面跳轉,其中方法如下:

/* 決定是否響應網頁的某個動作,例如加載,回退,前進,刷新等,在這個方法中,必須執行decisionHandler()代碼塊,并將是否允許這個活動執行在block中進行傳入 */ /* WKNavigationAction是網頁動作的抽象化,其中封裝了許多行為信息,后面會介紹 WKNavigationActionPolicy為開發者回執,枚舉如下: typedef NS_ENUM(NSInteger, WKNavigationActionPolicy) {//取消此次行為WKNavigationActionPolicyCancel,//允許此次行為WKNavigationActionPolicyAllow, } NS_ENUM_AVAILABLE(10_10, 8_0); */ -(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{decisionHandler(WKNavigationActionPolicyAllow); } //需要響應身份驗證時調用 同樣在block中需要傳入用戶身份憑證 -(void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler{//用戶身份信息NSURLCredential *newCred = [NSURLCredential credentialWithUser:@""password:@""persistence:NSURLCredentialPersistenceNone];// 為 challenge 的發送方提供 credential[[challenge sender] useCredential:newCredforAuthenticationChallenge:challenge];completionHandler(NSURLSessionAuthChallengeUseCredential,newCred); } //接收到數據后是否允許執行渲染 /* 其中,WKNavigationResponse為請求回執信息 WKNavigationResponsePokicy為開發者回執,枚舉如下: typedef NS_ENUM(NSInteger, WKNavigationResponsePolicy) {//取消渲染WKNavigationResponsePolicyCancel,//允許渲染WKNavigationResponsePolicyAllow, } NS_ENUM_AVAILABLE(10_10, 8_0); */ -(void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{decisionHandler(WKNavigationResponsePolicyAllow); } //=====================下面這個協議方法用于監聽流程========================================= //頁面加載啟動時調用 -(void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{} //當主機接收到的服務重定向時調用 -(void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{} //內容到達主機時調用 -(void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{} //主頁加載完成時調用 -(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{} //提交發生錯誤時調用 -(void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error{} //主頁數據加載發生錯誤時調用 -(void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(nonnull NSError *)error{} //進程被終止時調用 -(void)webViewWebContentProcessDidTerminate:(WKWebView *)webView{}

七、WKUIDelegate協議中方法解析

//創建新的webView時調用的方法 -(WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures{return webView; } //關閉webView時調用的方法 -(void)webViewDidClose:(WKWebView *)webView{} //下面這些方法是交互JavaScript的方法 //JavaScript調用alert方法后回調的方法 message中為alert提示的信息 必須要在其中調用completionHandler() -(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{NSLog(@"%@",message);completionHandler(); } //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"); }

八、擴展

首先,在注冊要被JavaScript調用的方法時需要設置代理,在不需要時需要將代理移除,WKUserContentController中也提供了移除這個代理的方法,如果不移除,將會造成WebView不能釋放。方法如下:

//注冊一個監聽方法 - (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name; //移除一個方法的監聽 - (void)removeScriptMessageHandlerForName:(NSString *)name;

同樣與注入JavaScript對應,也可以將注入的代碼移除,方法如下:

//注入一個JavaScript抽象對象 - (void)addUserScript:(WKUserScript *)userScript; //移除所有注入 - (void)removeAllUserScripts;

?在上面,經常會見到WKNavagationAction這個類,這個類中封裝的是一些頁面活動信息,如下:

@interface WKNavigationAction : NSObject //原頁面 @property (nonatomic, readonly, copy) WKFrameInfo *sourceFrame; //目標頁面 @property (nullable, nonatomic, readonly, copy) WKFrameInfo *targetFrame; //請求URL @property (nonatomic, readonly, copy) NSURLRequest *request; //活動類型 /* typedef NS_ENUM(NSInteger, WKNavigationType) {//鏈接激活WKNavigationTypeLinkActivated,//提交操作WKNavigationTypeFormSubmitted,//前進操作WKNavigationTypeBackForward,//刷新操作WKNavigationTypeReload,//重提交操作 例如前進 后退 刷新WKNavigationTypeFormResubmitted,//其他類型WKNavigationTypeOther = -1, } NS_ENUM_AVAILABLE(10_10, 8_0); */ @property (nonatomic, readonly) WKNavigationType navigationType; @end

?轉載自:http://my.oschina.net/u/2340880/blog/700345

總結

以上是生活随笔為你收集整理的iOS中WebKit框架应用与解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。