H5与iOS原生交互

作者: 娘亲Joanna | 来源:发表于2018-03-21 11:44 被阅读584次

    在H5与原生交互刚刚出来时候,就做了预研,后来公司需求就换了APICloud,以前学习的就快忘记了,特意做个总结。

    在预研的时候发现个很大的问题:第一次加载H5页面的时候,如果页面内容比较多的时候,需要长时间的加载时间,用户体验十分不好

    1. 交互流程

    1. 建一个对象 BLManagerOCModel 继承 NSObject 用于与H5交互

      1. 引入JavaScriptCore
    #import <JavaScriptCore/JavaScriptCore.h>
    
      1. 提供给js外部调用的方法
    #pragma mark  -------------暴露给外部调用的方法----------- 
    @protocol JavaScriptObjectiveCDelegate <JSExport>
    
    
    // JS调用此方法来调用OC的扫描设备的方法
    - (void)scanDevice:(NSString *)params;
    // 通过JSON传过来参数
    - (void)connectDevice:(NSString *)params;
    //取消设备的连接
    - (void)disconnectDevice:(NSString *)params;
    //发送蓝牙指令
    - (void)sendDataToDevice:(NSString *)params;
    //通过HTML页面 获取deviceId
    - (void)sendDeviceId :(NSString *)params;
    //获取后台的响应
    - (void)getResponseFromPlatform:(NSString *)response;
    
    
    //获取蓝牙的响应
    - (NSString *)getResponseFromBluetooth;
    //拿到的后台返回消息
    - (NSString *)getResponseFromPlatForm;
    
    
    
    @end
    
    
    • 3.遵循JavaScriptCore协议
    @interface BLManagerOCModel : NSObject<JavaScriptObjectiveCDelegate,CBCentralManagerDelegate,CBPeripheralDelegate>
    
    ////添加一个JSManagedValue用来保存JSValue
    @property (nonatomic, strong) JSManagedValue *jsManagerValue;
    @property (nonatomic, strong) JSContext *jsContext;
    @property (nonatomic, strong)JSValue *jsValue;
    
    
    @property (nonatomic, weak)UIWebView *webview;
    
    
      1. 实现BLManagerOCModel
    //oc与js的交互的方法:原生传值给H5  
    //参数jsContext为H5中的js方法,也就是回调的函数
    - (void)OCHtmlInteracticeWithJsContext:(NSString *)jsContext
                                    status:(NSInteger )status
                                      uuid:(NSString *)uuid
                                    extent:(NSString *)extend
                                  blueName:(NSString *)blueName {
        NSDictionary *reponseDict =  @{
                                       @"status": @(status),
                                       @"data": @[@{
                                                      @"uuid": uuid?uuid:@"",
                                                      @"mac":@"",
                                                      @"extend":extend,
                                                      @"blueName":blueName
                                                      }]
                                       };
        if (self.jsContext > 0) {
            JSValue *callBackValue =  self.jsContext[jsContext];
            if (callBackValue) {
                [self.jsContext[@"setTimeout"] callWithArguments:@[callBackValue,@0, reponseDict]];
            }
        }
    }
    
    
    //搜索设备,未绑定的情况下,
    //H5中的js的回调函数名为connectCallBack
    - (void)scanDevice:(NSString *)params{
        if (params == nil) {
            params = @"";
        }
        self.prefixName = params;
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            [self scanDevicesWithDevicePrefixName:self.prefixName UUID:nil timeoutInterval:10 completion:^(NSArray *devices, NSError *error) {
                if (!error) {
                    [self OCHtmlInteracticeWithJsContext:@"connectCallBack" status:AppscommResponseWithScanedfinished uuid:@"" extent:@"" blueName:@""];
                }else{
                    if (error.code == 6601) {
                        [self OCHtmlInteracticeWithJsContext:@"connectCallBack" status:AppscommResponseWithScanTimeOut uuid:@"" extent:@"" blueName:@""];
                    }else if (error.code == 6602){
                        [self OCHtmlInteracticeWithJsContext:@"connectCallBack" status:AppscommResponseWithSystemBluetoothIsClose uuid:@"" extent:@"" blueName:@""];
                    }
                }
            }];
        });
    }
    
    
    
    #pragma mark --------蓝牙交互模块--------------------
    //调用H5中js 的 blueJsManage.sendData 方法
    - (void)GetDeviceIdFromDeviceUUID:(NSString *)UUID{
    //在原生中使用H5的方法
        [self.webview stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"blueJsManage.sendData('%@',WatchIdResolve.getWatchIdCommand)",UUID]];
    }
    
    
    

    2. 一切准备就绪,在ViewController实现H5与原生交互

      1. 原生页面如下:
    #import "ViewController.h"
    #import "BLManagerOCModel.h"
    #import <JavaScriptCore/JavaScriptCore.h>
    
    @interface ViewController ()<UIWebViewDelegate>
    @property (nonatomic, strong)UIWebView *webView;
    @property (weak, nonatomic) IBOutlet UIButton *scanBtn;
    @property (weak, nonatomic) IBOutlet UIButton *connectBtn;
    @property (weak, nonatomic) IBOutlet UIButton *registerButton;
    @property (weak, nonatomic) IBOutlet UIButton *loginButton;
    @property (weak, nonatomic) IBOutlet UIButton *chooseUnit;
    @property (nonatomic, strong) JSContext *jsContext;
    @property (nonatomic, strong)BLManagerOCModel *OCModel;
    @end
    
    @implementation ViewController
    - (UIWebView *)webView {
        if (_webView == nil) {
            
            _webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 0,  0)];
            _webView.scalesPageToFit = YES;
            
            //引入js以及HTML文件
            NSURL *url = [[NSBundle mainBundle] URLForResource:@"loadJS" withExtension:@"html"];
            NSURLRequest *request = [NSURLRequest requestWithURL:url];
     
            [_webView loadRequest:request];
            _webView.delegate = self;
            
        }
        
        return _webView;
    }
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        
    //    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms:13764502892"]];
    //    [self loadJs];
        
        [self.view addSubview:self.webView];
        
        // 一个JSContext对象,就类似于Js中的window,只需要创建一次即可。
        self.jsContext = [[JSContext alloc] init];
        self.jsContext = [_webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
        
        BLManagerOCModel *model  = [[BLManagerOCModel alloc] init];
        //一进入界面就进行扫描
        //    [model scanDevice:@"sm"];
        self.jsContext[@"OCModel"] = model;
        model.jsContext = self.jsContext;
        model.webview = self.webView;
        self.OCModel = model;
        
        
        self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
            context.exception = exceptionValue;
            NSLog(@"异常信息:%@", exceptionValue);
        };
    
    
    }
    - (void)webViewDidFinishLoad:(UIWebView *)webView{
    
        
          [self.webView stringByEvaluatingJavaScriptFromString:@"var appsCloud = new AppsCloud('appscomm','http://new.fashioncomm.com',5000);"];
    }
    //蓝牙模块
        [self.OCModel GetDeviceIdFromDeviceUUID:@"7B481C41-354D-D646-F624-37CF24461216"];
    
      1. H5页面如些
    <!DOCTYPE html>
    <html >
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
             <title>测试IOS与JS之前的互调</title>
              <script src="http://apps.bdimg.com/libs/jquery/1.10.2/jquery.min.js"></script>
             <script type="text/javascript" src="blueJs.js"></script>
             <script type="text/javascript" src="apps.blue.js?v=1"></script>
             <script type = "text/javascript" src = "apps.blue.protocol.battery.js"></script>
             
            <style>
                *{
                    margin:40px;
     
                }
     
                </style>
            <script type = "text/javascript">
                
            function getDeviceId(macid,data){     /*获取deviceID的时候的回调  */
                var deviceId = JSON.stringify(data['msg']);
            }
            
            /*回调函数*/
            
            //提供给OC的函数
            var connectCallBack = function(argument) {
                alert( JSON.stringify(argument));
           
            }
        }
            
         </script>
     
            <style type="text/css">
                
                </style>
      
        </head>
        
        <body>
       
    //onclick 方法为js里的方法 供原生调用
       <input type = 'button' value = '获取watchid' style = 'font-size:18px; color:blue;' onclick = "blueJsManage.sendData('7B481C41-354D-D646-F624-37CF24461216',WatchIdResolve.getWatchIdCommand)"/>
       
       <input type = 'button' value = '扫描L设备' style = 'font-size:16px; color:red;' onclick = "blueJsManage.searchBlueIdentitys('L53A#00160')" >
           
           <input type  = 'button' value = '连接设备'  style = 'font-size:16px; color:red;' onclick = "blueJsManage.connectToWatch('L53A#00160')">
    
    
       
       </body>
      
    </html>
    
    
    代码结构

    相关文章

      网友评论

        本文标题:H5与iOS原生交互

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