iOS中WebKit框架應(yīng)用與解析
一、引言
在iOS8之前,在應(yīng)用中嵌入網(wǎng)頁(yè)通常需要使用UIWebView這樣一個(gè)類(lèi),這個(gè)類(lèi)通過(guò)URL或者HTML文件來(lái)加載網(wǎng)頁(yè)視圖,功能十分有限,只能作為輔助嵌入原生應(yīng)用程序中。雖然UIWebView也可以做原生與JavaScript交互的相關(guān)處理,然而也有很大的局限性,JavaScript要調(diào)用原生方法通常需要約定好協(xié)議之后通過(guò)Request來(lái)傳遞。WebKit框架中添加了一些原生與JavaScript交互的方法,增強(qiáng)了網(wǎng)頁(yè)視圖與原生的交互能力。并且WebKit框架中采用導(dǎo)航堆棧的模型來(lái)管理網(wǎng)頁(yè)的跳轉(zhuǎn),開(kāi)發(fā)者也可以更加容易的控制和管理網(wǎng)頁(yè)的渲染。關(guān)于UIWebView的相關(guān)使用,在前面的博客中有詳細(xì)介紹,地址如下。
二、WebKit框架概覽
WebKit框架中涉及的類(lèi)很多,框架的設(shè)計(jì)十分面向?qū)ο蠛湍K化,開(kāi)發(fā)者在使用時(shí)可以輕松的寫(xiě)出結(jié)構(gòu)清晰的代碼。在進(jìn)行使用前,我們首先應(yīng)該清楚整個(gè)框架的結(jié)構(gòu)和開(kāi)發(fā)思路,下面一張腦圖中基本列出了WebKit框架中所涉及到的所有重要的類(lèi)以及他們之間的相互關(guān)系:

如上圖所示,WebKit框架中最核心的類(lèi)應(yīng)該屬于WKWebView了,這個(gè)類(lèi)專(zhuān)門(mén)用來(lái)渲染網(wǎng)頁(yè)視圖,其他類(lèi)和協(xié)議都將基于它和服務(wù)于它。
WKWebView:網(wǎng)頁(yè)的渲染與展示,通過(guò)WKWebViewConfiguration可以進(jìn)行配置。
WKWebViewConfiguration:這個(gè)類(lèi)專(zhuān)門(mén)用來(lái)配置WKWebView。
WKPreference:這個(gè)類(lèi)用來(lái)進(jìn)行M相關(guān)設(shè)置。
WKProcessPool:這個(gè)類(lèi)用來(lái)配置進(jìn)程池,與網(wǎng)頁(yè)視圖的資源共享有關(guān)。
WKUserContentController:這個(gè)類(lèi)主要用來(lái)做native與JavaScript的交互管理。
WKUserScript:用于進(jìn)行JavaScript注入。
WKScriptMessageHandler:這個(gè)類(lèi)專(zhuān)門(mén)用來(lái)處理JavaScript調(diào)用native的方法。
WKNavigationDelegate:網(wǎng)頁(yè)跳轉(zhuǎn)間的導(dǎo)航管理協(xié)議,這個(gè)協(xié)議可以監(jiān)聽(tīng)網(wǎng)頁(yè)的活動(dòng)。
WKNavigationAction:網(wǎng)頁(yè)某個(gè)活動(dòng)的示例化對(duì)象。
WKUIDelegate:用于交互處理JavaScript中的一些彈出框。
WKBackForwardList:堆棧管理的網(wǎng)頁(yè)列表。
WKBackForwardListItem:每個(gè)網(wǎng)頁(yè)節(jié)點(diǎn)對(duì)象。
三、使用WKWebViewConfiguration對(duì)WebView進(jìn)行配置
使用下面的代碼可以創(chuàng)建一個(gè)WKWebView視圖,創(chuàng)建WebView視圖時(shí),需要使用WKWebViewConfiguration來(lái)進(jìn)行配置:
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中可以進(jìn)行配置的方法和屬性如下:
//設(shè)置進(jìn)程池
WKProcessPool * pool = [[WKProcessPool alloc]init];
config.processPool = pool;
WKProcessPool類(lèi)中沒(méi)有暴露任何屬性和方法,配置為同一個(gè)進(jìn)程池的WebView會(huì)共享數(shù)據(jù),例如Cookie、用戶(hù)憑證等,開(kāi)發(fā)者可以通過(guò)編寫(xiě)管理類(lèi)來(lái)分配不同維度的WebView在不同進(jìn)程池中。
//進(jìn)行偏好設(shè)置
WKPreferences * preference = [[WKPreferences alloc]init];
//最小字體大小 當(dāng)將javaScriptEnabled屬性設(shè)置為NO時(shí),可以看到明顯的效果
preference.minimumFontSize = 0;
//設(shè)置是否支持javaScript 默認(rèn)是支持的
preference.javaScriptEnabled = YES;
//設(shè)置是否允許不經(jīng)過(guò)用戶(hù)交互由javaScript自動(dòng)打開(kāi)窗口
preference.javaScriptCanOpenWindowsAutomatically = YES;
config.preferences = preference;
WKPerference實(shí)例為WebView提供一個(gè)偏好設(shè)置。
//設(shè)置內(nèi)容交互控制器 用于處理JavaScript與native交互
WKUserContentController * userController = [[WKUserContentController alloc]init];
//設(shè)置處理代理并且注冊(cè)要被js調(diào)用的方法名稱(chēng)
[userController addScriptMessageHandler:self name:@"name"];
//js注入,注入一個(gè)測(cè)試方法。
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專(zhuān)門(mén)用來(lái)管理native與JavaScript的交互行為,addScriptMessageHandler:name:方法來(lái)注冊(cè)要被js調(diào)用的方法名稱(chēng),之后再JavaScript中使用window.webkit.messageHandlers.name.postMessage()方法來(lái)像native發(fā)送消息,支持OC中字典,數(shù)組,NSNumber等原生數(shù)據(jù)類(lèi)型,JavaScript代碼中的name要和上面注冊(cè)的相同。在native代理的回調(diào)方法中,會(huì)獲取到JavaScript傳遞進(jìn)來(lái)的消息,如下:
-(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
//這里可以獲取到JavaScript傳遞進(jìn)來(lái)的消息
}
WKScriptMessage類(lèi)是JavaScript傳遞的對(duì)象實(shí)例,其中屬性如下:
//傳遞的消息主體
@property (nonatomic, readonly, copy) id body;
//傳遞消息的WebView
@property (nullable, nonatomic, readonly, weak) WKWebView *webView;
//傳遞消息的WebView當(dāng)前頁(yè)面對(duì)象
@property (nonatomic, readonly, copy) WKFrameInfo *frameInfo;
//消息名稱(chēng)
@property (nonatomic, readonly, copy) NSString *name;
WKUserContentController實(shí)例的addUserScript:用于注入JavaScript代碼,后面會(huì)專(zhuān)門(mén)介紹。
//設(shè)置數(shù)據(jù)存儲(chǔ)store
config.websiteDataStore = [WKWebsiteDataStore defaultDataStore];
WebKit框架采用其本身的緩存框架,WKWebsiteDataStore類(lèi)用來(lái)處理數(shù)據(jù)的存儲(chǔ),其中屬性和方法如下:
@interface WKWebsiteDataStore : NSObject
//獲取默認(rèn)的存儲(chǔ)器 此存儲(chǔ)器為持久性的會(huì)被寫(xiě)入磁盤(pán)
+ (WKWebsiteDataStore *)defaultDataStore;
//獲取一個(gè)臨時(shí)的存儲(chǔ)器
+ (WKWebsiteDataStore *)nonPersistentDataStore;
//存儲(chǔ)器是否是臨時(shí)的
@property (nonatomic, readonly, getter=isPersistent) BOOL persistent;
//所有可以存儲(chǔ)的類(lèi)型
+ (NSSet *)allWebsiteDataTypes;
@end
//設(shè)置是否將網(wǎng)頁(yè)內(nèi)容全部加載到內(nèi)存后再渲染
config.suppressesIncrementalRendering = NO;
//設(shè)置HTML5視頻是否允許網(wǎng)頁(yè)播放 設(shè)置為NO則會(huì)使用本地播放器
config.allowsInlineMediaPlayback =YES;
//設(shè)置是否允許ariPlay播放
config.allowsAirPlayForMediaPlayback = YES;
//設(shè)置視頻是否需要用戶(hù)手動(dòng)播放設(shè)置為NO則會(huì)允許自動(dòng)播放
config.requiresUserActionForMediaPlayback = NO;
//設(shè)置是否允許畫(huà)中畫(huà)技術(shù) 在特定設(shè)備上有效
config.allowsPictureInPictureMediaPlayback = YES;
//設(shè)置選擇模式 是按字符選擇 還是按模塊選擇
/*
typedef NS_ENUM(NSInteger, WKSelectionGranularity) {
//按模塊選擇
WKSelectionGranularityDynamic,
//按字符選擇
WKSelectionGranularityCharacter,
} NS_ENUM_AVAILABLE_IOS(8_0);
*/
config.selectionGranularity = WKSelectionGranularityCharacter;
//設(shè)置請(qǐng)求的User-Agent信息中應(yīng)用程序名稱(chēng) iOS9后可用
config.applicationNameForUserAgent = @"HS";
四、WKWebView中的屬性和方法解析
下面列舉了WKWebView中常用的屬性和方法。
//設(shè)置導(dǎo)航代理
@property (nullable, nonatomic, weak) id navigationDelegate;
//設(shè)置UI代理
@property (nullable, nonatomic, weak) id UIDelegate;
//導(dǎo)航列表
@property (nonatomic, readonly, strong) WKBackForwardList *backForwardList;
//通過(guò)url加載網(wǎng)頁(yè)視圖
- (nullable WKNavigation *)loadRequest:(NSURLRequest *)request;
//通過(guò)文件加載網(wǎng)頁(yè)視圖
- (nullable WKNavigation *)loadFileURL:(NSURL *)URL allowingReadAccessToURL:(NSURL *)readAccessURL NS_AVAILABLE(10_11, 9_0);
//通過(guò)HTML字符串加載網(wǎng)頁(yè)視圖
- (nullable WKNavigation *)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL;
//通過(guò)data數(shù)據(jù)加載網(wǎng)頁(yè)視圖
- (nullable WKNavigation *)loadData:(NSData *)data MIMEType:(NSString *)MIMEType characterEncodingName:(NSString *)characterEncodingName baseURL:(NSURL *)baseURL NS_AVAILABLE(10_11, 9_0);
//渲染導(dǎo)航列表中的某個(gè)網(wǎng)頁(yè)節(jié)點(diǎn)
- (nullable WKNavigation *)goToBackForwardListItem:(WKBackForwardListItem *)item;
//網(wǎng)頁(yè)標(biāo)題
@property (nullable, nonatomic, readonly, copy) NSString *title;
//網(wǎng)頁(yè)的url
@property (nullable, nonatomic, readonly, copy) NSURL *URL;
//網(wǎng)頁(yè)是否正在加載中
@property (nonatomic, readonly, getter=isLoading) BOOL loading;
//加載進(jìn)度 可以監(jiān)聽(tīng)這個(gè)屬性的值配合UIProgressView來(lái)設(shè)計(jì)進(jìn)度條
@property (nonatomic, readonly) double estimatedProgress;
//是否全部是安全連接
@property (nonatomic, readonly) BOOL hasOnlySecureContent;
//證書(shū)列表
@property (nonatomic, readonly, copy) NSArray *certificateChain;
//是否可以回退
@property (nonatomic, readonly) BOOL canGoBack;
//是否可以前進(jìn)
@property (nonatomic, readonly) BOOL canGoForward;
//回退網(wǎng)頁(yè)
- (nullable WKNavigation *)goBack;
//前進(jìn)網(wǎng)頁(yè)
- (nullable WKNavigation *)goForward;
//刷新網(wǎng)頁(yè)
- (nullable WKNavigation *)reload;
//忽略緩存的刷新
- (nullable WKNavigation *)reloadFromOrigin;
//停止加載
- (void)stopLoading;
//執(zhí)行JavaScript代碼
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ __nullable)(__nullable id, NSError * __nullable error))completionHandler;
//是否允許右滑返回手勢(shì)
@property (nonatomic) BOOL allowsBackForwardNavigationGestures;
WKBackForwardList類(lèi)為導(dǎo)航管理的網(wǎng)頁(yè)列表類(lèi),其中屬性方法意義如下:
@interface WKBackForwardList : NSObject
//當(dāng)前所在的網(wǎng)頁(yè)節(jié)點(diǎn)
@property (nullable, nonatomic, readonly, strong) WKBackForwardListItem *currentItem;
//前進(jìn)的一個(gè)網(wǎng)頁(yè)節(jié)點(diǎn)
@property (nullable, nonatomic, readonly, strong) WKBackForwardListItem *forwardItem;
//回退的一個(gè)網(wǎng)頁(yè)節(jié)點(diǎn)
@property (nullable, nonatomic, readonly, strong) WKBackForwardListItem *backItem;
//獲取某個(gè)index的網(wǎng)頁(yè)節(jié)點(diǎn)
- (nullable WKBackForwardListItem *)itemAtIndex:(NSInteger)index;
//獲取回退的節(jié)點(diǎn)數(shù)組
@property (nonatomic, readonly, copy) NSArray *backList;
//獲取前進(jìn)的節(jié)點(diǎn)數(shù)組
@property (nonatomic, readonly, copy) NSArray *forwardList;
@end
在WebKit中,網(wǎng)頁(yè)節(jié)點(diǎn)被抽象成為了WKBackForwardListItem類(lèi),這個(gè)類(lèi)中封裝的屬性如下:
@interface WKBackForwardListItem : NSObject
//當(dāng)前節(jié)點(diǎn)的URL
@property (readonly, copy) NSURL *URL;
//當(dāng)前節(jié)點(diǎn)的標(biāo)題
@property (nullable, readonly, copy) NSString *title;
//創(chuàng)建此WebView的初始URL
@property (readonly, copy) NSURL *initialURL;
五、關(guān)于native與JavaScript交互
WebKit中的native與JavaScript的交互主要有4類(lèi)。
1.JavaScript調(diào)用native方法
這種方式是由WKUserContentController注冊(cè),并在代理方法中實(shí)現(xiàn)的。
2.native調(diào)用JavaScript方法
這種方式通過(guò)WKWebView直接調(diào)用evaluteJavaScript:completionHandler:方法來(lái)實(shí)現(xiàn)。
3.將JavaScript代碼注入
這種方式可以在網(wǎng)頁(yè)中注入一些自定義的JavaScript代碼,也可以注入自定義的方法,再使用evaluteJavaScript:completionHandler:來(lái)調(diào)用方法。JavaScript代碼的注入也是通過(guò)WKUserContentController來(lái)完成的,使用addUserScript:方法來(lái)注入JavaScript,其中需要通過(guò)WKUserScript類(lèi)來(lái)生成要注入的對(duì)象,這個(gè)類(lèi)使用如下方法來(lái)進(jìn)行實(shí)例化:
/*
source為要注入的js代碼
WKUserScriptInjectionTime設(shè)置注入的時(shí)機(jī)
forMainFrameOnly參數(shù)設(shè)置是否只在主頁(yè)面注入
typedef NS_ENUM(NSInteger, WKUserScriptInjectionTime) {
//原js代碼運(yùn)行前注入
WKUserScriptInjectionTimeAtDocumentStart,
//原js代碼運(yùn)行后注入
WKUserScriptInjectionTimeAtDocumentEnd
} NS_ENUM_AVAILABLE(10_10, 8_0);
*/
- (instancetype)initWithSource:(NSString *)source injectionTime:(WKUserScriptInjectionTime)injectionTime forMainFrameOnly:(BOOL)forMainFrameOnly;
4.通過(guò)WKUIDelegate來(lái)交互
這種方式主要用于相應(yīng)JavaScript中的彈出框,后面會(huì)詳細(xì)介紹這個(gè)協(xié)議。
六、WKNavagationDelegate中方法解析
WKNavagationDelegate協(xié)議重要有兩個(gè)作用,監(jiān)聽(tīng)頁(yè)面渲染流程與控制頁(yè)面跳轉(zhuǎn),其中方法如下:
/*
決定是否響應(yīng)網(wǎng)頁(yè)的某個(gè)動(dòng)作,例如加載,回退,前進(jìn),刷新等,在這個(gè)方法中,必須執(zhí)行decisionHandler()代碼塊,并將是否允許這個(gè)活動(dòng)執(zhí)行在block中進(jìn)行傳入
*/
/*
WKNavigationAction是網(wǎng)頁(yè)動(dòng)作的抽象化,其中封裝了許多行為信息,后面會(huì)介紹
WKNavigationActionPolicy為開(kāi)發(fā)者回執(zhí),枚舉如下:
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);
}
//需要響應(yīng)身份驗(yàn)證時(shí)調(diào)用 同樣在block中需要傳入用戶(hù)身份憑證
-(void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler{
//用戶(hù)身份信息
NSURLCredential *newCred = [NSURLCredential credentialWithUser:@""
password:@""
persistence:NSURLCredentialPersistenceNone];
// 為 challenge 的發(fā)送方提供 credential
[[challenge sender] useCredential:newCred
forAuthenticationChallenge:challenge];
completionHandler(NSURLSessionAuthChallengeUseCredential,newCred);
}
//接收到數(shù)據(jù)后是否允許執(zhí)行渲染
/*
其中,WKNavigationResponse為請(qǐng)求回執(zhí)信息
WKNavigationResponsePokicy為開(kāi)發(fā)者回執(zhí),枚舉如下:
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);
}
//=====================下面這個(gè)協(xié)議方法用于監(jiān)聽(tīng)流程=========================================
//頁(yè)面加載啟動(dòng)時(shí)調(diào)用
-(void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
}
//當(dāng)主機(jī)接收到的服務(wù)重定向時(shí)調(diào)用
-(void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{
}
//內(nèi)容到達(dá)主機(jī)時(shí)調(diào)用
-(void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{
}
//主頁(yè)加載完成時(shí)調(diào)用
-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
}
//提交發(fā)生錯(cuò)誤時(shí)調(diào)用
-(void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error{
}
//主頁(yè)數(shù)據(jù)加載發(fā)生錯(cuò)誤時(shí)調(diào)用
-(void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(nonnull NSError *)error{
}
//進(jìn)程被終止時(shí)調(diào)用
-(void)webViewWebContentProcessDidTerminate:(WKWebView *)webView{
}
七、WKUIDelegate協(xié)議中方法解析
//創(chuàng)建新的webView時(shí)調(diào)用的方法
-(WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures{
return webView;
}
//關(guān)閉webView時(shí)調(diào)用的方法
-(void)webViewDidClose:(WKWebView *)webView{
}
//下面這些方法是交互JavaScript的方法
//JavaScript調(diào)用alert方法后回調(diào)的方法 message中為alert提示的信息 必須要在其中調(diào)用completionHandler()
-(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
NSLog(@"%@",message);
completionHandler();
}
//JavaScript調(diào)用confirm方法后回調(diào)的方法 confirm是js中的確定框,需要在block中把用戶(hù)選擇的情況傳遞進(jìn)去
-(void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
NSLog(@"%@",message);
completionHandler(YES);
}
//JavaScript調(diào)用prompt方法后回調(diào)的方法 prompt是js中的輸入框 需要在block中把用戶(hù)輸入的信息傳入
-(void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
NSLog(@"%@",prompt);
completionHandler(@"123");
}八、擴(kuò)展
首先,在注冊(cè)要被JavaScript調(diào)用的方法時(shí)需要設(shè)置代理,在不需要時(shí)需要將代理移除,WKUserContentController中也提供了移除這個(gè)代理的方法,如果不移除,將會(huì)造成WebView不能釋放。方法如下:
//注冊(cè)一個(gè)監(jiān)聽(tīng)方法
- (void)addScriptMessageHandler:(id )scriptMessageHandler name:(NSString *)name;
//移除一個(gè)方法的監(jiān)聽(tīng)
- (void)removeScriptMessageHandlerForName:(NSString *)name;
同樣與注入JavaScript對(duì)應(yīng),也可以將注入的代碼移除,方法如下:
//注入一個(gè)JavaScript抽象對(duì)象
- (void)addUserScript:(WKUserScript *)userScript;
//移除所有注入
- (void)removeAllUserScripts;
在上面,經(jīng)常會(huì)見(jiàn)到WKNavagationAction這個(gè)類(lèi),這個(gè)類(lèi)中封裝的是一些頁(yè)面活動(dòng)信息,如下:
@interface WKNavigationAction : NSObject
//原頁(yè)面
@property (nonatomic, readonly, copy) WKFrameInfo *sourceFrame;
//目標(biāo)頁(yè)面
@property (nullable, nonatomic, readonly, copy) WKFrameInfo *targetFrame;
//請(qǐng)求URL
@property (nonatomic, readonly, copy) NSURLRequest *request;
//活動(dòng)類(lèi)型
/*
typedef NS_ENUM(NSInteger, WKNavigationType) {
//鏈接激活
WKNavigationTypeLinkActivated,
//提交操作
WKNavigationTypeFormSubmitted,
//前進(jìn)操作
WKNavigationTypeBackForward,
//刷新操作
WKNavigationTypeReload,
//重提交操作 例如前進(jìn) 后退 刷新
WKNavigationTypeFormResubmitted,
//其他類(lèi)型
WKNavigationTypeOther = -1,
} NS_ENUM_AVAILABLE(10_10, 8_0);
*/
@property (nonatomic, readonly) WKNavigationType navigationType;
@end