1. 程式人生 > >wkwebview與js通訊學習總結(一)

wkwebview與js通訊學習總結(一)

  • EvaluateJavaScript方法為非同步
  1. - UIWebview: 中是同步執行的,直接呼叫 - (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;方法返回執行結果
  2. - WKWebView改為了```block```的方式進行值返回,並且該方法的執行是非同步的- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ __nullable)(__nullable id, NSError * __nullable error))completionHandler;

延伸:執行JS方法的使用場景之一,就是獲取當前webview的title,```WKWebView```提供了新屬性title,如果是想獲取title,可以直接使用```WKWebView```的title屬性.

  • cookie設定方式不同
  1. - UIWebView:NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];[storage setCookie:cookieKey value:cookieValue];通過該方式設定的,為全域性的cookie,專案中任意的```UIWebView```均攜帶一樣的cookie.設定之後不需要做額外的操作.
  2. - WKWebView網頁將不再能獲取預設的cookie,如果需要攜帶cookie,需要做一些操作:
             初始化cookie, ```NSString *cookie =  @"document.cookie='cookieKey=cookieValue'";```
             注入cookie

             獲取當前的userContentController WKUserContentController *userContentController = self.wkWebView.configuration.userContentController;

             注入scrpit: WKUserScript *script = [[WKUserScript alloc] initWithSource:cookieValue injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];

            [userContentController addUserScript:script];

注意:注入script時引數indectionTime有兩個可選項```WKUserScriptInjectionTimeAtDocumentStart```和```WKUserScriptInjectionTimeAtDocumentEnd```,

我們看一下官方文件對於這兩個選項的解釋:

```WKUserScriptInjectionTimeAtDocumentStart``` : 注入時機為document的元素生成之後,其他內容load之前.

```WKUserScriptInjectionTimeAtDocumentEnd``` : 注入時機為document全部load完成,任意子資源load完成之前.

一般情況下,如果想盡早注入cookie,在```WKUserScriptInjectionTimeAtDocumentStart```時完成即可,但是有一種特殊情況,即目前的診療圈為後端渲染,資料請求依賴cookie中的```sessionKey```,而前端頁面的元素依賴後端返回的資料,因此,有一個問題,即cookie是在頁面元素生成之後注入的,而在這之前,後端需要獲取cookie,那麼應該怎麼辦呢??

     在requestHeader內注入cookie

     NSString *cookie =  @"cookieKey1=cookieValue1;cookieKey2=cookieValue2";```

     [mutableRequest addValue:cookie forHTTPHeaderField:@"Cookie"];

     這樣在網路請求開始時,requestHeader將攜帶cookie.

  • WKWebView預設禁止了一些跳轉

     - UIWebView 開啟ituns.apple.com跳轉到appStore, 撥打電話, 喚起郵箱等一系列操作UIWebView預設支援的.

    - WKWebView預設禁止了以上行為,除此之外,js端通過```window.open()```開啟新的網頁的動作也被禁掉了.

如何支援呢?

######可以跳轉appStore或者撥號

-(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {

if(webView != self.wkWebView) {

decisionHandler(WKNavigationActionPolicyAllow);

return;

}

UIApplication *app = [UIApplication sharedApplication];

if ([url.scheme isEqualToString:@"tel"])

{

if ([app canOpenURL:url])

{

[app openURL:url];

decisionHandler(WKNavigationActionPolicyCancel);

return;

}

}

if ([url.absoluteString containsString:@"ituns.apple.com"])

{

if ([app canOpenURL:url])

{

[app openURL:url];

decisionHandler(WKNavigationActionPolicyCancel);

return;

}

}

decisionHandler(WKNavigationActionPolicyAllow);

}

######支援window.open()

需要開啟新介面是,WKWebView的代理```WKUIDelegate```方法

- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures

會攔截到window.open()事件.

只需要我們在在方法內進行處理

if (!navigationAction.targetFrame.isMainFrame) {

[webView loadRequest:navigationAction.request];

}

######支援alert()

WKWebView預設不響應js的alert()事件,如何可以開啟alert許可權呢?

代理```WKUIDelegate```方法

- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler

將會獲取到alert的資訊,但是不會彈出alert.

在方法內部

[alertController addAction:[UIAlertAction actionWithTitle:@"OK"

style:UIAlertActionStyleCancel

handler:^(UIAlertAction *action) {

completionHandler();

}]];

if ([self.delegate isKindOfClass:[UIViewController class]]) {

UIViewController *controller = (UIViewController *)self.delegate;

[controller presentViewController:alertController animated:YES completion:^{}];

}