IOSでUICWebView、WKWebViewのJSインタラクティブ


クライアントの開発をしたら、JSの相互作用が避けられないと思います。アップルインターフェースに簡易パッケージを作りました。
JSExport-->UICbView+Interaction、WKScript Message Handler-->WKWebView+Interactionは後で使うために用意されています。
コードは非常に簡潔です。ここを見てください。https://github.com/V5zhou/JSInteraction.git
古い方式
古いインタラクション方式はUICWebView Delegateによって実現されました。JSとクライアントはジャンプページパラメータを定義し、ジャンプする際にキーワードをキャプチャし、業務を処理します。
iOS端:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
  NSString *urlString = [[request URL] absoluteString];
  if ([urlString isEqualToString:@"objc://loading"]) {
    if (_gotoRootViewController) {
      _gotoRootViewController();
    }
  }
  return YES;
}
JS端:

<!DOCTYPE html>
<html>
  <title>test</title>
  <meta charset="utf-8">
    <body>
      <a href="javascript:document.location = 'objc://loading'" rel="external nofollow" class="btn">      </a>
    </body>
</html>
UICWebView+JSExport方式
JavaScript Core.frame ewarkを導入して、私の拡張タイプを導入します。「UnibView+Interaction.h」。
使い方
OC調JS:

[_webView InterActionToJs:@"alertMobile('15625298071')"];
JS OC:

- (void)webViewDidFinishLoad:(UIWebView *)webView {
  [self.webView InterActionToOc:^(InterActionOcType functionType, NSDictionary *param) {
    switch (functionType) {
      case InterActionOcType_alert:
      {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:param[@"title"] message:param[@"content"] delegate:nil cancelButtonTitle:nil otherButtonTitles:@"  ", nil];
        [alert show];
      }
        break;
      case InterActionOcType_present:
      {
        self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
        Class Cls = NSClassFromString(param[@"toController"]);
        BOOL isAnimate = [param[@"animate"] boolValue];
        UIViewController *ctl = [[Cls alloc] init];
        [self presentViewController:ctl animated:isAnimate completion:nil];
      }
        break;

      default:
        break;
    }
  }];
}

アクションを追加

//         
typedef NS_ENUM(NSUInteger, InterActionOcType) {
  InterActionOcType_alert = 0,
  InterActionOcType_present,
  InterActionOcType_xxxxxxx,   //          
};
また、対応するhtmlにJSを追加し、パラメータを辞書形式にパッケージします。例:

function myPresent(ctl) {
      var param = new Array();
      param["animate"] = 1;
      param["toController"] = "SecondViewController";
      WebViewInteraction.callBack(1, param);
    }
その中でもcalBackはこのJSExportで実現されました。

@protocol WebViewJSExport <JSExport>
JSExportAs
(callBack /** callBack   js      */,
 - (void)awakeOC:(InterActionOcType)type param:(NSDictionary *)param
 );
@end
WKWebView+WKScript Message Handler方式
WebKit.frame eworkを導入して、私の拡張タイプ「WKWebView+Interactions.h」を導入します。
使い方
OC調JS:

[self.wkWebView InterActionToJs:@"JSReloadTitle('     JS  ,    !')"];
JS OC:

//      
  [self.wkWebView registerScriptTypes:@{@"OCDismiss" : @(WKInterActionOcType_dismiss),
                     @"OCShowAlert" : @(WKInterActionOcType_alert)}];

  [self.wkWebView InterActionToOc:^(WKInterActionOcType functionType, NSDictionary *param) {
    switch (functionType) {
      case WKInterActionOcType_dismiss:
      {
        BOOL isAnimate = [param[@"animate"] boolValue];
        [self dismissViewControllerAnimated:isAnimate completion:nil];
      }
        break;
      case WKInterActionOcType_alert:
      {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"JS    " message:nil delegate:self cancelButtonTitle:@"  " otherButtonTitles:@"  ", nil];
        alert.alertViewStyle = UIAlertViewStylePlainTextInput;
        [alert show];
      }
        break;
      default:
        break;
    }
  }];

アクションを追加

//         
typedef NS_ENUM(NSUInteger, WKInterActionOcType) {
  WKInterActionOcType_alert = 0,
  WKInterActionOcType_dismiss,
  WKInterActionOcType_xxxxxxx,   //          
};
また、対応するhtmlにJSを追加し、パラメータを辞書形式にパッケージします。例:

//js oc
function myDismiss() {
  window.webkit.messageHandlers.OCDismiss.postMessage({"animate" : 1});  //   OCDismiss      
}
この中でcalBackはWKScript Message Handlerによって実現されます。

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
  dispatch_async(dispatch_get_main_queue(), ^{
    NSString *name = message.name;
    NSDictionary *value = message.body;
    WKInterActionOcType type = [self.typeDict[name] integerValue];
    if (self.block) {
      self.block(type, value);
    }
  });
}
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。