JS和原生交互

现在H5和原生的交互在日常开发中经常用的,很多APP为了优化APP,更加便捷灵活的更新页面,有很多页面交给了H5来开发,那么JS和原生的交互就很重要了。

现在常用的主要有两种方式:第三方WebViewJavascriptBridge和原生的交互

首先先来讲一下第一种WebViewJavascriptBridge

首先要引入WebViewJavascriptBridge,可以用cocoapods来引入

pod 'WebViewJavascriptBridge'

可以新建一个工具类然后引入

#import <WebViewJavascriptBridge.h>

@property (nonatomic, strong) WebViewJavascriptBridge *bridge;
@property(nonatomic,strong)WKWebView * webView;


然后和webview建立关系

- (void)configureWithWebView:(WKWebView *)webView {
    self.webView = webView;
    // 3.开启日志
    [WebViewJavascriptBridge enableLogging];
    
    // 4.给webView建立JS和OC的沟通桥梁
    self.bridge = [WebViewJavascriptBridge bridgeForWebView:self.webView];
    [self.bridge setWebViewDelegate:self];
    
}
这里是JS调用OC的API:访问相册
-(void)openCamera{
    /* JS调用OC的API:访问相册 */
//    self.Controller = [self getCurrentViewController];
    [self.bridge registerHandler:@"openCamera" handler:^(id data, WVJBResponseCallback responseCallback) {
        NSLog(@"需要%@图片", data[@"count"]);
        
//        UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypeCamera;
//        if ([UIImagePickerController isSourceTypeAvailable:(UIImagePickerControllerSourceTypeCamera)]) {
            UIImagePickerController * picker =[[UIImagePickerController alloc] init];
            picker.delegate = self;
            //设置拍照后的图片可被编辑
            picker.allowsEditing = YES;
//            picker.sourceType = sourceType;
        self.Controller = [self getCurrentViewController];
            //        [self presentModalViewController:picker animated:YES];被废弃的
            [self.Controller presentViewController:picker animated:YES completion:nil];
//        }
    }];
    
    
     /* JS调用OC的API:访问底部弹窗 */
    [self.bridge registerHandler:@"showSheet" handler:^(id data, WVJBResponseCallback responseCallback) {
        UIAlertController *vc = [UIAlertController alertControllerWithTitle:@"你猜我出不出来?" message:@"嘻嘻嘻嘻!!" preferredStyle:UIAlertControllerStyleActionSheet];
        UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
        UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:nil];
        [vc addAction:cancelAction];
        [vc addAction:okAction];
        [[self getCurrentViewController] presentViewController:vc animated:YES completion:nil];
    }];
}

在Controller页面创建一个webview


 self.webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 300, self.view.frame.size.width, 300)];
    [self.view addSubview:self.webView];
    self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 600, 100, 100)];
    [self.view addSubview:self.imageView];

NSString *indexPath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
    NSString *appHtml = [NSString stringWithContentsOfFile:indexPath encoding:NSUTF8StringEncoding error:nil];
    NSURL *baseUrl = [NSURL fileURLWithPath:indexPath];
    [self.webView loadHTMLString:appHtml baseURL:baseUrl];
    [[HLWebTool HLWebToolAPI] configureWithWebView:self.webView];

    [[HLWebTool HLWebToolAPI] openCamera];//这个方法要调用的

index中的代码

<!doctype html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0">
        <style>
            body{
                background-color:paleturquoise;
            }

            button{
                border:0;
                width: 150px;
                height: 35px;
                background-color: orangered;
                color: white;
                font-size: 16px;
                border-radius: 6px;
            }
        </style>
    </head>
    
    <body>
        <h2>JS调用OC中的方法</h2>
        <button id="btn">访问OC相册</button>
        <button id="btn1">调用OC提示窗</button>
        <p></p>
    </body>
    <script>
       // 这段代码是固定的,必须要放到js中
       function setupWebViewJavascriptBridge(callback) {
            if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
            if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
            window.WVJBCallbacks = [callback];
            var WVJBIframe = document.createElement('iframe');
            WVJBIframe.style.display = 'none';
            WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
            document.documentElement.appendChild(WVJBIframe);
            setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
        }
    
        // 与OC交互的所有JS方法都要在这里注册,才能让OC和JS之间相互调用
       setupWebViewJavascriptBridge(function(bridge) {

           /* JS给OC提供公开的API, 在OC中可以手动调用此API, 并且可以接收OC中传过来的参数,同时可回调OC */

           // 获取用户信息
           bridge.registerHandler('getUserInfo', function(data, responseCallback) {
               console.log("OC中传递过来的参数:", data);
               // 把处理好的结果返回给OC
               responseCallback({"userID":"DX001", "userName":"旋之华", "age":"18", "otherName":"旋之华"})
           });

           //  弹框输出
           bridge.registerHandler('alertMessage', function(data, responseCallback) {
               alert(data);
               console.log(data);
           });

           //  动态跳转到京东商城
           bridge.registerHandler('pushToNewWebSite', function(data, responseCallback) {
               window.location.href = data.url;
           });

           bridge.registerHandler('insertImgToWebPage', function(data, responseCallback) {

                var img = document.createElement('img');
                img.src = data.url;
                img.width = 200;
                document.body.appendChild(img);

           });


           /* OC给JS提供公开的API, 在JS中可以手动调用此API, 并且可以接收OC中传过来的参数,同时可回调OC */
                                    
           // 调用OC中的打开相册方法
           document.getElementById('btn').onclick = function () {
               bridge.callHandler('openCamera', {'count':'10张'}, function responseCallback(responseData) {
                   console.log("OC中返回的参数:", responseData)
               });
           };

           document.getElementById('btn1').onclick = function () {
               bridge.callHandler('showSheet', '', function responseCallback(responseData) {
                   console.log("OC中返回的参数:", responseData)
               });
           };
       })
    </script>
</html>

以上是JS调用OC的方法,接下来讲OC调用JS


Controller里面添加点击方法
UIButton * userBut = [[UIButton alloc] initWithFrame:CGRectMake(0, 50, 100, 50)];
    [self.view addSubview:userBut];
    [userBut setTitle:@"获取用户信息" forState:(UIControlStateNormal)];
    [userBut addTarget:self action:@selector(getUserinfo) forControlEvents:(UIControlEventTouchUpInside)];
///*  获取用户信息  */
- (void)getUserinfo {
    // 调用JS中的API
    [[HLWebTool HLWebToolAPI] getUserinfo];
    
}


工具类中实现方法
- (void)getUserinfo {
    // 调用JS中的API
    [self.bridge callHandler:@"getUserInfo" data:@{@"userId":@"DX001"} responseCallback:^(id responseData) {
        NSString *userInfo = [NSString stringWithFormat:@"%@,姓名:%@,年龄:%@", responseData[@"userID"], responseData[@"userName"], responseData[@"age"]];
        UIAlertController *vc = [UIAlertController alertControllerWithTitle:@"从网页端获取的用户信息" message:userInfo preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
        UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:nil];
        [vc addAction:cancelAction];
        [vc addAction:okAction];
        [[self getCurrentViewController] presentViewController:vc animated:YES completion:nil];
    }];
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 参考 总评: oc 与js的交互,1.有原生的方式,oc 调js简单,js调oc 麻烦(协议拦截"实现的交互方式)...
    杨大虾阅读 394评论 0 3
  • 像我们在开发App的过程中难免会遇到App与前端H5的交互,那么我们就会碰到webView这样的控件,但是与前端J...
    陈先生的干货店阅读 1,057评论 0 2
  • 在项目开发中,我们常常遇到这种情况,一个功能性界面需要分享到其他平台,或者是一个较复杂,原生框架不易实现,需要经常...
    zhangferry阅读 4,576评论 7 25
  • 需求说明 目前的APP客户端内,经常需要嵌入H5页面进行混合开发。这样,在开发过程中就会涉及到原生客户端和H5交互...
    kobe55阅读 1,393评论 0 3
  • 随着H5技术的兴起,在iOS开发过程中,难免会遇到原生应用需要和H5页面交互的问题。其中会涉及方法调用及参数传值等...
    Chris_js阅读 3,230评论 1 8

友情链接更多精彩内容