oc与js交互实用的东西

  因为之前换了个部门,产品是一款混合开发的移动端APP,当然啦,本人也是一位菜鸟中的菜鸟,最开始只用OC做移动端的开发,后来有机会接触到混合开了。接触到新的知识当然也是好事也是一件挑战,现在主流混合开发的APP多数就是原生代码把基本的一个UI布局布好后嵌套WEBVIEW,好处自然不用说,主要代码实现都用JS 去写,迭代开发快,减少发版本的时间,所以嘛总会涉及到OC和JS的交互,自己也在网上找了很多方法很多文章,但是总是无法满足自己的需求,多数都只是那句经典的语法 stringByEvaluatingJavaScriptFromString,没错,这句语法确实是好用,但是非常局限,也满足不了我的需求。QQ:75200314  需要DEMO的可以加Q

  说先说明几点:

        1.这个文章也是我在忙碌当中抽时间出来写的,主要目的教会你怎样通过OC去调JS的方法(或者一个返回值)还有JS端怎么去调OC端的方法(或者返回值),OC端代码没有封装,WEB端代码也没有用jQuery什么的

        2.页面UI极度简陋,花时间去美化UI调整各种frame不如发篇博文实在,花多十来分钟看代码肯定能看懂,初学OC和JS的人都能看懂

        3.文中有个方法是自己尝试出来的,底层的东西没有太多时间去关注,暂时没有发现出现程序崩的问题,虽然会警告

  然后开始代码:先把WEB端的代码截图发出来  基本就是秒懂的代码,一共有两个页面,都会进行分别说明,代码截图如下:

第一个页面
以下这份代码可以看到有两个button和一个方法,方法是一个返回字符串:
id=“goFowardBtn”的Button触发的是跳转到另一个WEB的页面

id=“getOC”的Button没有触发任何事件,但这个button的value值在后面的代码通过OC端的代码来改变



然后就是第二WEB页面
这个页面同样有两个Button:
第一个id=“goBackBtn”的Button触发的是回到第一个WEB页面;
第二个id=“goToOcSecondVC”的Button的绑定事件是调用OC代码中一个叫 goToSecondView的方法



然后就是OC端两个controller的代码了这个比较重点,先把代码截图show出来
第一个Controller的代码如下,注意一点需要加个库JavaScriptCore.framework
首先看- (void)webViewDidFinishLoad:(UIWebView *)webView 这个方法,只要webview重新加载完成的时候就会调用此方法,web页面中的title值在加载完成后当然也能在这个方法里拿到,有两个方法。
方法一:系统自带的语法直接去调用就可以,此方法比较蛋疼,stringByEvaluatingJavaScriptFromString  看方法名就大概猜到返回值的,所以我们用控件titlelabel.text来接收这个返回值就可以了,当然你用其他控件的属性去接收随意。
_titlelabel.text= [_webview stringByEvaluatingJavaScriptFromString:@"document.title"];

方法二就:比较麻烦,但是这是后面可以继续有话说下去的前提吧。
通过JavaScriptCore.framework框架 建立 oc与js通讯的桥梁 首先创建JSContext 对象(此处通过当前webView的键获取到jscontext)这句实例化的代码是非常关键的。
    JSContext *context = [_webview valueForKeyPath:@“documentView.webView.mainFrame.javaScriptContext"];

然后我们想通过这个桥梁去获取WEB第一个页面pushdata() 这个方法的返回值,就需要先把JS端这个方法用一个OC对象来保存起来,当然是用NSString
    NSString *alertJS = @"pushdata()"; //用字符串对象保存对应js中的方法名
    
    NSString *getdata = [context evaluateScript:alertJS]; //实例化对象context调用js的方法名,得到返回值用OC端字符串对象保存起来
    
    NSLog(@"----%@",getdata); //成功打印js的返回值,OK  OC端要拿到JS端的一个参数搞定

然后我们来看看JS端如何调OC端的一个返回值,
看- (void)btnclick 这个方法,依然是先创建JSContext的实例化对象,然后通过一句代码,
context[@"str"] = [self pushOcdata]; 这里要注意等号的右边是OC 这边的返回值 ,把这个返回值赋值给一个叫str的变量,然后可以看到打印看到结果。
NSString *changevalue = @“document.getElementById('getOC').value=str"; 等号的右边意思就是我们把刚才叫str的变量赋值给WEB端id=“getOC”的button.value的属性,然后通过一个字符串对象保存我要执行的JS代码,最终由一开始JSContext的实例化对象context 去执行这个操作就可以了。这样JS那边就成功调取我OC 这边的一个返回值了,注意在OC 这边不同类型用不同的变量去声明,而JS端声明变量就一个var就够了,然而有了这个方法后你会发现只要你懂一点JS的代码,要改变一个JS的变量值几乎全部在OC 这端就可以实现了。

接下来我们再看看 evaluateScript 这个方法的另外一个例子,在evaluateScript 这个方法后面直接写一个函数 function add(a,b){return a+b;} ,
然后下面几句代码至关重要,
JSValue *add = context[@“add"];
NSLog(@"Func-----:%@",add);
JSValue *sum = [add callWithArguments:@[@(7),@(8)]];
NSLog(@"Sum-----:%d",[sum toInt32]);

我们可以对比下以下两句代码
context[@"str"] = [self pushOcdata];       JSValue *add = context[@“add"];
第一句代码是把等号右边OC的返回值赋值给左边JS中一个叫str的变量,
第二句代码是等号右边JS的函数给OC端JSValue对象来保存,
最后一句 JSValue *sum = [add callWithArguments:@[@(7),@(8)]]; 是把给7、8两个参数传到add这个函数里,返回值依旧用JSValue来保存,最后还要调用一个toInt32的方法把结果打印出来。





下面这个截图重点就在于要在- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 这个方法里写如何拦截js那边的方法,因为我在JS那边的链接是以ios:// 开头的,其他都是一些UI创建以及WEBVIEW加载本地html文件的方法,就没什么好说的了。




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值