美文网首页iOSiOS与网页交互相关
网页(js)与oc(iOS)之间的方法调用及传值

网页(js)与oc(iOS)之间的方法调用及传值

作者: 清都 | 来源:发表于2017-07-27 15:36 被阅读254次

    最后更新时间:2017-07-27

    调用的对象bsg只是一个名字,不影响代码内容,请随意命名

    调用及传值方法

    前期准备

    • bsg对象的作用在于在网页(js)端识别iOS端方法,一般网页调用方法直接调用即可,调用特定对象的方法则用类似onclick="bsg.call()"的方法,通过对象.函数名的方式进行调用。
    • 本方法将iOS端作为特定对象(即bsg)调用,则通过协议,网页端能直接调用本地即iOS端的方法。
    • 故使用前需声明JSObjcDelegate协议,并于- (void)webViewDidFinishLoad:(UIWebView *)webView方法内设置delegate
    • 需要导入#import <JavaScriptCore/JavaScriptCore.h>

    iOS调用网页方法

    iOS端调用(此处网页端函数名为:Callback)
        JSValue *Callback = self.jsContext[@"Callback"];
        //传值给web端
        [Callback callWithArguments:@[@"唤起本地OC回调完成"]];
    
    网页端接收iOS端的信息
    
    var Callback = function(str)
    {
        alert(str);
    }
    
    • str即Arguments里面的信息@“唤起本地OC回调完成”
    • alert为网页端信息展示方法

    网页调用iOS方法

    网页端调用
    <input type="button" value="唤起本地方法(call)" onclick="bsg.call()">
    
    • 此处bsg.call()即该按钮点击调用bsg对象下的call()方法
    iOS端设置

    1.协议方法

    @protocol JSObjcDelegate <JSExport>
    //bsg对象调用的JavaScript方法,必须声明
    - (void)call;
    - (void)getCall:(NSString *)callString;
    
    @end
    
    • 以上方法名字与网页端一致,调用形式如:bsg.call()

    2.代理

    - (void)webViewDidFinishLoad:(UIWebView *)webView {
        
        // 设置javaScriptContext上下文
        self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
        //将bsg对象指向自身//网页端设置点击方法:bsg.call(),call()方法由bsg对象调用,此处将自身设置为bsg对象,用来调用本地方法而非网页方法
        self.jsContext[@"bsg"] = self;
        self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
            context.exception = exceptionValue;
            NSLog(@"异常信息:%@", exceptionValue);
        };
    }
    

    3.对应方法

    
    - (void)getCall:(NSString *)callString{
        NSLog(@"Get:%@", callString);
        // 成功回调JavaScript的方法Callback
        JSValue *Callback = self.jsContext[@"alerCallback"];
        [Callback callWithArguments:nil];
    }
    

    附录

    网页代码

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    </head>
    <body>
    <div style="margin-top: 20px">
    <h2>JS与OC交互</h2>
    <input type="button" value="唤起本地方法(call)" onclick="bsg.call()">
    </div>
    <div>
    <input type="button" value="唤起getCall:(NSString *)callString传值" onclick="call()">
    </div>
    
    <script>
    
    var call = function()
    {
        var callInfo = JSON.stringify({"abc": "这只是一串数据"});
            bsg.getCall(callInfo);
    }
    
    var Callback = function(str)
    {
        alert(str);
    }
    var alerCallback = function()
    {
        alert('成功');
    }
    </script>
    </body>
    </html>
    

    iOS端代码

    #import "ViewController.h"
    #import <JavaScriptCore/JavaScriptCore.h>
    
    @protocol JSObjcDelegate <JSExport>
    //bsg对象调用的JavaScript方法,必须声明
    - (void)call;
    - (void)getCall:(NSString *)callString;
    
    @end
    
    @interface ViewController ()<UIWebViewDelegate,JSObjcDelegate>
    @property (nonatomic, strong) JSContext *jsContext;
    @property (strong, nonatomic)  UIWebView *webView;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.webView = [[UIWebView alloc]initWithFrame:CGRectMake(0, 20, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
        self.webView.delegate = self;
        //加载html文件——此处根据需要更改,url可以设为本地加载或者通过路径
        //通过本地则需要
    //    NSString* path = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
    //    NSURL* url = [NSURL fileURLWithPath:path];
        NSURL* url = [NSURL URLWithString:@"/Users/admin/Desktop/text.html"];
        NSURLRequest* request = [NSURLRequest requestWithURL:url] ;
        [self.webView loadRequest:request];
        
        [self.view addSubview:self.webView];
        
    }
    
    - (void)webViewDidFinishLoad:(UIWebView *)webView {
        
        // 设置javaScriptContext上下文
        self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
        //将bsg对象指向自身//网页端设置点击方法:bsg.call(),call()方法由bsg对象调用,此处将自身设置为bsg对象,用来调用本地方法而非网页方法
        self.jsContext[@"bsg"] = self;
        self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
            context.exception = exceptionValue;
            NSLog(@"异常信息:%@", exceptionValue);
        };
    }
    
    
    - (void)call{
        NSLog(@"call");
        //调用网页端函数:Callback
        // 之后在回调JavaScript的方法Callback把内容传出去
        JSValue *Callback = self.jsContext[@"Callback"];
        //传值给web端
        [Callback callWithArguments:@[@"唤起本地OC回调完成"]];
    }
    
    - (void)getCall:(NSString *)callString{
        NSLog(@"Get:%@", callString);
        // 成功回调JavaScript的方法Callback
        JSValue *Callback = self.jsContext[@"alerCallback"];
        [Callback callWithArguments:nil];
    }
    
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    @end
    
    网页打开后效果

    参考文章:iOS开发-基于原生JS与OC方法互相调用并传值(附HTML代码)

    相关文章

      网友评论

        本文标题:网页(js)与oc(iOS)之间的方法调用及传值

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