美文网首页iOS 技术分享
iOS - 使用JSBridge实现OC与h5的传值

iOS - 使用JSBridge实现OC与h5的传值

作者: Joh蜗牛 | 来源:发表于2020-10-24 09:58 被阅读0次

    使用WebViewJavascriptBridge实现

    1.三方下载:

    链接:(https:/pan.baidu.com/s/1mEpIWW7t7XPRplqzVlTmRA 密码:l2a2)
    (请手动把https后改为双斜杠)

    2.使用代码:(.m文件)

    
    
    #import "CustomerServiceViewController.h"
    #import <WebKit/WebKit.h>
    #import "WebViewJavascriptBridge.h"
    
    @interface CustomerServiceViewController ()<WKNavigationDelegate,WKUIDelegate,UIWebViewDelegate>
    @property (nonatomic, strong) UIWebView *uiWebView;
    @property (nonatomic,strong) WKWebView *wkWebView;
    
    @property (nonatomic,strong) WebViewJavascriptBridge *bridge;
    
    
    @end
    
    @implementation CustomerServiceViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
    
        self.title = @"客户服务";
        self.view.backgroundColor = kWhiteColor;
    
    //    [self.view addSubview:self.uiWebView];
        [self.view addSubview:self.wkWebView];
    
        // 名称
        NSString *name = [GlobelConfig getNullStr:[UserInfo shareInstance].idCardName];
        // 手机号
        NSString *phone = [GlobelConfig getNullStr:[UserInfo shareInstance].registerPhone];
        // token
        NSDictionary *TokenDic = [[NSUserDefaults standardUserDefaults]objectForKey:@"loginUserInfoDic"];
        NSString *token = [GlobelConfig getNullStr:TokenDic[@"token"]];
    
        // bridge.getUserInfo()
        NSDictionary *param = @{@"token":token,@"phone":phone,@"nickname":name};
        NSString *jsonStr = [param mj_JSONString];
    
        // 开启日志
        [WebViewJavascriptBridge enableLogging];
    
        // 给哪个webview建立JS与OjbC的沟通桥梁
        self.bridge = [WebViewJavascriptBridge bridgeForWebView:self.uiWebView];
        [self.bridge setWebViewDelegate:self];
    
    
        // JS主动调用OjbC的方法
        // 这是JS会调用getUserIdFromObjC方法,这是OC注册给JS调用的
        // JS需要回调,当然JS也可以传参数过来。data就是JS所传的参数,不一定需要传
        // OC端通过responseCallback回调JS端,JS就可以得到所需要的数据
        [self.bridge registerHandler:@"getUserInfo" handler:^(id data, WVJBResponseCallback responseCallback) {
          NSLog(@"js call getUserIdFromObjC, data from js is %@", data);
    // 这里的data为JS发送给OC的数据
          if (responseCallback) {
            // 反馈给JS
            responseCallback(param);
          }
        }];
        [self.bridge callHandler:@"getUserInfo" data:jsonStr responseCallback:^(id responseData) {
          NSLog(@"from js: %@", responseData);
        }];
    
    
    }
    
    #pragma mark - UIWebView
    - (UIWebView *)uiWebView{
        if (!_uiWebView) {
            self.uiWebView = [[UIWebView alloc] initWithFrame:CGRectMake(0,0, K_SCREEN_WIDTH, K_SCREEN_HEIGHT - KNavHeight - TabbarSafeBottomMargin)];
            self.uiWebView.delegate = self;
    
            [self setAutomaticallyAdjustsScrollViewInsets:NO];
    
            NSString *url = @"http://";
            NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
            [self.uiWebView loadRequest:request];
    
        }
        return _uiWebView;
    }
    
    
    
    - (void)webViewDidStartLoad:(UIWebView *)webView {
        [SVProgressHUD show];
    }
    
    - (void)webViewDidFinishLoad:(UIWebView *)webView {
        [SVProgressHUD dismiss];
    }
    
    #pragma mark - WKWebView
    - (WKWebView *)wkWebView{
        if (!_wkWebView) {
            self.wkWebView = [[WKWebView alloc] initWithFrame:CGRectMake(0,0, K_SCREEN_WIDTH, K_SCREEN_HEIGHT - KNavHeight - TabbarSafeBottomMargin)];
    
            self.wkWebView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth ;
            self.wkWebView.contentMode = UIViewContentModeRedraw;
            self.wkWebView.opaque = YES;
            self.wkWebView.UIDelegate =self;
            self.wkWebView.navigationDelegate = self;
            self.wkWebView.allowsBackForwardNavigationGestures = YES;
    
            [self setAutomaticallyAdjustsScrollViewInsets:NO];
    
            NSString *url = @"http://";
            NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
            [self.wkWebView loadRequest:request];
    
        }
        return _wkWebView;
    }
    
    // 页面开始加载时调用
    - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
        [SVProgressHUD show];
    }
    
    // 页面加载失败时调用
    - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
        [SVProgressHUD dismiss];
    }
    // 页面加载完成之后调用
    - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
        [SVProgressHUD dismiss];
    }
    
    - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
    {
        NSString *urlStr = [webView.URL absoluteString];
        if ([urlStr rangeOfString:@"login"].location != NSNotFound)
        {
            //[SVProgressHUD dismiss];
            decisionHandler(WKNavigationActionPolicyCancel);
    
    
        }
        else if ([urlStr rangeOfString:@"register"].location != NSNotFound)
        {
            // [SVProgressHUD dismiss];
            decisionHandler(WKNavigationActionPolicyCancel);
    
        }
        else
        {
            decisionHandler(WKNavigationActionPolicyAllow);
        }
    }
    
    #pragma mark - WKUIDelegate
    // js交互
    - (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
    {
        NSLog(@"%@",message);
        completionHandler();
    
        if ([message isEqualToString:@"back"])
        {
            [self.navigationController popViewControllerAnimated:YES];
        }
    
    }
    
    @end
    
    

    3.h5的代码:

    (参考https:/www。cnblogs。com/iOS-mt/p/10438723.html)
    (请手动把https后改为双斜杠,"。"改为".")
    1.iOS代码:

    // 1.新建WebView
    self.webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:self.webView];
    
    // 2.加载网页
    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];
    
    // 3.开启日志
    [GCWebviewJSBridge setEnableLogging];
    
    // 4.给webView建立JS和OC的沟通桥梁
    _bridge = [GCWebviewJSBridge bridgeForWebView:self.webView];
    [_bridge setwebViewDelegate:self];
    

    2.JS的准备工作:
    之前是只写一套, 发现iOS行了Android又不行了; Android行了iOS又不行了. 最后才知道需要写两套

    // 这段代码是固定的,必须要放到js中
    function setupWebViewJavascriptBridge(callback) {
       //Android
       if (window.GCWebviewAndroidJSBridge) {
           callback(GCWebviewAndroidJSBridge)
       } else {
           document.addEventListener(
             ‘GCWebviewAndroidJSBridgeReady‘
             , function() {
             callback(GCWebviewAndroidJSBridge)
             },
             false
         );
       }
    
       //iOS
       if (window.GCWebviewJSBridge) {
           return callback(GCWebviewJSBridge);
       }
       if (window.KBWVJSBCallBacks) {
           return window.KBWVJSBCallBacks.push(callback);
       }
       window.KBWVJSBCallBacks = [callback];
       var GCWVJSBIframe = document.createElement(‘iframe‘);
       GCWVJSBIframe.style.display = ‘none‘;
       GCWVJSBIframe.src = ‘gcwvjsbscheme://__GC_BRIDGE_LOADED__‘;
       document.documentElement.appendChild(GCWVJSBIframe);
       setTimeout(function() { document.documentElement.removeChild(GCWVJSBIframe) }, 0);
    }
    
    

    iOS注册方法提供给JS调用

    [_bridge registerObjCHandler:@"openCamera" handler:^(id data, GCWVJSBResponseCallback responseCallback) {
        NSLog(@"需要%@图片", data[@"count"]);
        UIImagePickerController *imageVC = [[UIImagePickerController alloc] init];
        imageVC.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        [self presentViewController:imageVC animated:YES completion:nil];
    }];
    
    

    JS调用该方法的代码片段

    bridge.callHandler(‘openCamera‘, {‘count‘:‘10张‘}, function responseCallback(responseData) {
       console.log("OC中返回的参数:", responseData)
    });
    

    JS注册方法提供给iOS调用. (oc 调用 js)
    iOS注册提供用户信息方法

    /* 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":"旋之华"})
    });
    

    iOS调用JS中的方法, 获得用户信息

    // 调用JS中的API
    [self.bridge callHandler:@"getUserInfo" data:@{@"userId":@"DX001"} responseCallback:^(id responseData) {
        NSString *userInfo = [NSString stringWithFormat:@"%@,姓名:%@,年龄:%@", responseData[@"userID"], responseData[@"userName"], responseData[@"age"]];
    }];
    

    参考文献

    (请手动把https后改为双斜杠,"。"改为".")

    https:/www。jianshu。com/p/83f99a02c992

    https:/www。jianshu。com/p/d45ce14278c7

    https:/blog.csdn.net/cnsxhza985/article/details/20053839?utm_medium=distribute.pc_relevant_bbs_down.none-task--2

    https:/www。cnblogs。com/iOS-mt/p/10438723.html

    相关文章

      网友评论

        本文标题:iOS - 使用JSBridge实现OC与h5的传值

        本文链接:https://www.haomeiwen.com/subject/ntjimktx.html