zoukankan      html  css  js  c++  java
  • iOS 混合开发 —— OC和H5交互

    纵观所有iOSH5交互的方案,有以下几种:

    第一种:有很多的app直接使用在webview的代理中通过拦截的方式与native进行交互,通常是通过拦截url scheme判断是否是我们需要拦截处理的url及其所对应的要处理的功能是什么。任意版本都支持。

    第二种:iOS7之后出了JavaScriptCore.framework用于与JS交互,但是不支持iOS6,对于还需要支持iOS6app,就不能考虑这个了。若需要了解,看最后的推荐阅读。

    第三种:WebViewJavascriptBridge开源库使用,本质上,它也是通过webview的代理拦截scheme,然后注入相应的JS

    第四种:react-native,这个没玩过(与前三种不同)。

     

    1、UIWebView 和 js 交互  【JavaScriptCore.framework】

     

    ViewController.m:

    #import "WebViewController.h"
    #import "WebViewModel.h"
    
    @interface WebViewController () <UIWebViewDelegate>
    
    @property (nonatomic, strong) UIWebView *webView;
    @property (nonatomic, strong) JSContext *jsContext;
    
    @property (nonatomic, strong) WebViewModel *model;
    @end
    
    @implementation WebViewController
    
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        [self.view addSubview:self.webView];
        [self createButtons];
        
        //  // 一个JSContext对象,就类似于Js中的window,只需要创建一次即可。
        //  self.jsContext = [[JSContext alloc] init];
        //
        //  // jscontext可以直接执行JS代码。
        //  [self.jsContext evaluateScript:@"var num = 10"];
        //  [self.jsContext evaluateScript:@"var squareFunc = function(value) { return value * 2 }"];
        //  // 计算正方形的面积
        //  JSValue *square = [self.jsContext evaluateScript:@"squareFunc(num)"];
        //
        //  // 也可以通过下标的方式获取到方法
        //  JSValue *squareFunc = self.jsContext[@"squareFunc"];
        //  JSValue *value = [squareFunc callWithArguments:@[@"20"]];
        //  NSLog(@"%@", square.toNumber);
        //  NSLog(@"%@", value.toNumber);
    }
    
    - (void)createButtons {
        NSArray *array = @[@"ocCallJS",
                           @"ocCallJSWithString",
                           //@"ocCallJSWithTitle:message",
                           //@"ocCallJSWithDictionary",
                           //@"ocCallJSWithArray"
                           ];
        
        NSInteger index = 0;
        for (NSString *string in array) {
            UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
            [button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
            [button setTitle:string forState:UIControlStateNormal];
            [button addTarget:self action:@selector(buttonAciton:) forControlEvents:UIControlEventTouchUpInside];
            
            button.frame = CGRectMake(kScreenWidth-300, 100+(index * 50), 280, 30);
            
            button.layer.borderColor = [UIColor redColor].CGColor;
            button.layer.borderWidth = 1;
            button.layer.cornerRadius = 3;
            
            index ++;
            
            [self.view addSubview:button];
        }
    }
    
    
    - (void)buttonAciton:(UIButton *)button {
        if ([button.currentTitle isEqualToString:@"ocCallJS"]) {
            [self.model ocCallJS];
            
        }else if ([button.currentTitle isEqualToString:@"ocCallJSWithString"]) {
            [self.model ocCallJSWithString:@"myocString"];
            
        }else if ([button.currentTitle isEqualToString:@"ocCallJSWithTitle:message"]) {
    //        [self.model ocCallJSWithString];
            
        }else if ([button.currentTitle isEqualToString:@"ocCallJSWithDictionary"]) {
            [self.model ocCallJSWithDictionary:@{@"title":@"myoctitle",@"message":@"myocmessage"}];
            
        }else if ([button.currentTitle isEqualToString:@"ocCallJSWithArray"]) {
            [self.model ocCallJSWithArray:@[@"myoctitle",@"myocmessage",@"30"]];
            
        }
    }
    
    
    - (UIWebView *)webView {
        if (_webView == nil) {
            _webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
            
            NSURL *url = [[NSBundle mainBundle] URLForResource:@"callEach" withExtension:@"html"];
            [_webView loadRequest:[NSURLRequest requestWithURL:url]];
            
            //忽略web页面与_WebView组件的大小关系如果设置为YES可以执行缩放,但是web页面加载出来的时候,就会缩小到UIWebView组件的大小
            _webView.scalesPageToFit = NO;
            _webView.delegate = self;
        }
        
        return _webView;
    }
    
    #pragma mark - UIWebViewDelegate
    - (void)webViewDidFinishLoad:(UIWebView *)webView {
        self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
        
        WebViewModel *model  = [[WebViewModel alloc] init];
        self.jsContext[@"CallEachModel"] = model;
        model.jsContext = self.jsContext;
        model.webView = self.webView;
        model.currentVC = self;
        self.model = model;
        
        self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
            context.exception = exceptionValue;
            NSLog(@"异常信息:%@", exceptionValue);
        };
    }
    
    - (void)webViewDidStartLoad:(UIWebView *)webView {
        
    }
    
    @end
    

      

     model.h:

     

    #import <Foundation/Foundation.h>
    
    
    @protocol WebViewJSExport <JSExport>
    
    /** 遵守了 协议后 这些方法就暴露给 js 调用 **/
    
    
    /** jsCallOC **/
    - (void)jsCallOC;
    - (void)jsCallOCWithString:(NSString *)string;
    
    //js调用时候取函数名就好了 不要冒号 jsCallOCWithTitleMessage
    - (void)jsCallOCWithTitle:(NSString *)title message:(NSString *)msg;
    
    - (void)jsCallOCWithDictionary:(NSDictionary *)dictionary;
    - (void)jsCallOCWithArray:(NSArray *)array;
    
    
    
    /** ocCallJS **/
    - (void)ocCallJS;
    - (void)ocCallJSWithString:(NSString *)string;
    - (void)ocCallJSWithTitle:(NSString *)title message:(NSString *)message;
    
    - (void)ocCallJSWithDictionary:(NSDictionary *)dictionary;
    - (void)ocCallJSWithArray:(NSArray *)array;
    
    
    /** callEach **/
    - (void)jsCallOCAndOCCallJSWithParams:(NSDictionary *)params;
    - (void)ocCallJSAndJSCallOCWithParams:(NSDictionary *)params;
    
    
    @end
    
    
    @class BaseViewController;
    @interface WebViewModel : NSObject <WebViewJSExport>
    
    @property (nonatomic, weak) JSContext *jsContext;
    @property (nonatomic, weak) UIWebView *webView;
    
    @property (nonatomic, weak) BaseViewController *currentVC;
    
    @end
    

     

      

     

    model.m

     

    #import "WebViewModel.h"
    #import "BaseViewController.h"
    
    @implementation WebViewModel
    
    
    #pragma mark - jsCallOC
    
    - (void)jsCallOC {
        dispatch_async(dispatch_get_main_queue(), ^{
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil
                                                            message:@"jsCallOC"
                                                           delegate:nil
                                                  cancelButtonTitle:@"I konw"
                                                  otherButtonTitles:nil, nil];
            [alert show];
        });
    }
    
    
    - (void)jsCallOCWithString:(NSString *)string {
        dispatch_async(dispatch_get_main_queue(), ^{
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:string
                                                            message:nil
                                                           delegate:nil
                                                  cancelButtonTitle:@"I konw"
                                                  otherButtonTitles:nil, nil];
            [alert show];
        });
    }
    - (void)jsCallOCWithTitle:(NSString *)title message:(NSString *)msg {
        dispatch_async(dispatch_get_main_queue(), ^{
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
                                                            message:msg
                                                           delegate:nil
                                                  cancelButtonTitle:@"I konw"
                                                  otherButtonTitles:nil, nil];
            [alert show];
        });
    }
    
    
    
    - (void)jsCallOCWithDictionary:(NSDictionary *)dictionary {
        dispatch_async(dispatch_get_main_queue(), ^{
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:dictionary[@"title"]
                                                            message:dictionary[@"message"]
                                                           delegate:nil
                                                  cancelButtonTitle:@"I konw"
                                                  otherButtonTitles:nil, nil];
            [alert show];
        });
        
        NSLog(@"===== %@",dictionary);
    }
    
    - (void)jsCallOCWithArray:(NSArray *)array {
        dispatch_async(dispatch_get_main_queue(), ^{
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:array[0]
                                                            message:array[1]
                                                           delegate:nil
                                                  cancelButtonTitle:@"I konw"
                                                  otherButtonTitles:nil, nil];
            [alert show];
        });
        
        NSLog(@"===== %@",array);
    }
    
    
    
    
    #pragma mark - OCCallJS
    - (void)ocCallJS {
        JSValue *jsFunc = self.jsContext[@"func1"];
        [jsFunc callWithArguments:nil];
    }
    
    
    - (void)ocCallJSWithString:(NSString *)string {
        NSInteger arc = arc4random()%1000;
        JSValue *jsFunc = self.jsContext[@"func2"];
        [jsFunc callWithArguments:@[@{@"title": @"change--> myoctitle", @"message": @(arc)}]];
    }
    
    
    
    - (void)ocCallJSWithTitle:(NSString *)title message:(NSString *)message {
    
    }
    
    - (void)ocCallJSWithDictionary:(NSDictionary *)dictionary {
    
    }
    - (void)ocCallJSWithArray:(NSArray *)array {
       
    }
    
    
    #pragma mark - callEach
    - (void)jsCallOCAndOCCallJSWithParams:(NSDictionary *)params {
        [self.currentVC createTopView];
        self.currentVC.field.text = params[@"title"];
        
        [self.currentVC setBlock:^(NSString *string){
            if (string != nil && string.length > 0) {
                JSValue *jsFunc = self.jsContext[@"func2"];
                [jsFunc callWithArguments:@[@{@"title":@"js 调出来topView 输入填充到html:" , @"message": string}]];
            }
        }];
    }
    
    
    - (void)ocCallJSAndJSCallOCWithParams:(NSDictionary *)params {
        JSValue *jsFunc = self.jsContext[@"func3"];
        [jsFunc callWithArguments:@[@{@"title": @"myoctitle", @"message": @"myocmessage"}]];
    }
    
    @end
    

     

      

     github地址: https://github.com/lc081200/H5ObjCExample

  • 相关阅读:
    Codeforces 358 D. Dima and Hares
    sublime Text3配置及快捷键、插件推荐总结
    免费WiFi,仅仅为好久没联系的你们
    史上最简单的带流控功能的http server
    微软2014校园招聘笔试试题
    python 3Des 加密
    MySQL slave状态之Seconds_Behind_Master
    APP安全环节缺失,手游运营商怎样应对APP破解困境
    读完了csapp(中文名:深入理解计算机系统)
    static使用方法小结
  • 原文地址:https://www.cnblogs.com/saytome/p/7133552.html
Copyright © 2011-2022 走看看