小的做为一个iOS程序猿,可能研究JavaScript以及H5相关的知识并非为了真正的要去转行作这一方面,其实更多的为了要研究OC中的JavaScriptCore框架,JavaScriptCore框架主要是用来实现iOS与H5的交互.固然了,最先我曾经写过iOS浅谈webView的JS一种用法.(去掉web显示页的广告),这种算得上最简单的iOS与H5的交互了.如今混合编程愈来愈多,H5的相对讲多,因此研究JavaScriptCore框架是至关有必要的.好了不扯这些没用的了,来搞今天的主题---JavaScriptCore框架,首先来讲说JavaScriptCore框架几个经常使用的类.javascript
在作OC与H5的交互以前,咱们须要先导入JavaScriptCore框架.css
#import <JavaScriptCore/JavaScriptCore.h>
而后咱们进入JavaScriptCore框架的JavaScriptCore.h,咱们发现总共以下有几个类.java
<script type="text/javascript"> var myObject = "myObject"; </script>
而后咱们在OC的代码中以下表示,其中self.context表明着已经初始化完成的JSContext对象. JSValue *myObject = self.context[@"myObject"];
固然了,咱们若是须要在OC中使用JSValue对象,那么咱们可能须要适当的转换一下他的类型,框架提供了不少方法.好比上面的例子咱们想要打印的话就能够以下所示. NSLog(@"%@",[myObject toString]);
self.context[@"native"] = self;
在进行iOS与H5的交互以前,咱们须要作的是对JSContext对象进行初始化的设置,全程是在webView的- (void)webViewDidFinishLoad:(UIWebView *)webView这个代理方法中进行的.因此咱们须要对webView进行初始化以及设置代理,这里就不过多的言语了.咱们直接看一下在代理方法中如何对JSContext对象进行初始化设置.代码以下所示.web
- (void)webViewDidFinishLoad:(UIWebView *)webView{ //对JSContext对象进行初始化 self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; //验证JSContext对象是否初始化成功 self.context.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) { context.exception = exceptionValue; }; }
上一个模块咱们已经对JSContext对象进行了初始化,那么要使用JavaScript调取OC代码主要有两种方式,一种是使用block(简单粗暴);另一种是使用JSExport协议(决胜千里).编程
block方式比较简单,也是我比价推荐的一种,可是要注意防止循环引用问题的发生.首先咱们先说一下不带有参数的函数调用,也就是说咱们不须要从网页那边有参数的传值,好比跳转页面等等.代码以下所示.
HTML文件中的<body>标签的按钮代码安全
<button onclick="myAction();" style="">点击按钮返回上一个页面</button>
OC中在- (void)webViewDidFinishLoad:(UIWebView *)webView
方法中对block块进行代码实现.并发
__weak typeof(self)temp = self; self.context[@"myAction"] = ^(){ [temp.navigationController popViewControllerAnimated:YES]; };
接下来咱们看一下,经过页面的传值,咱们把H5标签的值做为参数进行传值操做,而且调用OC的block进行打印.
HTML文件中的<body>标签的div标签代码(一个输入框,一个按钮)框架
<input type="text" name="输入框" id="textField" placeholder="请输入要打印的信息" /> <button onclick="log(document.getElementById('textField').value);">打印输入框信息</button>
而后咱们在OC的代码中实现如下block函数.其中string参数就是网页中输入框的值.函数
self.context[@"log"] = ^(NSString *string){ NSLog(@"%@",string); };
效果图以下所示.坐标是手机模拟器,右边是Xcode控制台.学习
<button onclick="native.myLog();">调用OC中myLog方法</button>
咱们须要把native对象指定为当前控制器,也就是本身.这句代码是在- (void)webViewDidFinishLoad:(UIWebView *)webView
方法中实现的. self.context[@"native"] = self;
而后咱们要写一个继承于JSExport的协议,协议以下所示.这里我要作一下对JSExportAs(PropertyName,Selector)这个宏定义作一下解释,也就说在PropertyName表明着JS函数的名称,而Selector表明着OC的协议方法,要注意的是Selector必需要有参数,不论是否须要传值.(不知因此然.😭,求大神讲解) @protocol WebExport <JSExport> JSExportAs (myLog , - (void)myOCLog :(NSString *)string ); @end
定义好了方法以后,咱们就让当前的控制器遵照协议.实现代理方法. @interface JavaScriptCallOCViewController ()<UIWebViewDelegate,WebExport>
- (void)myOCLog :(NSString *)string{ NSLog(@"你好,世界!"); }
iOS浅谈webView的JS一种用法.(去掉web显示页的广告)中咱们说过一种比较简单的经过OC调取JavaScript函数的方式,固然了,咱们就是使用stringByEvaluatingJavaScriptFromString
方法添加了一个JS语句.代码以下所示.具体能够查看原文.
- (void)webViewDidFinishLoad:(UIWebView *)webView{ [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.getElementsByClassName('adpic')[0].style.display = 'none'"]; }
今天咱们说一下如何使用JavaScriptCore让OC调用JavaScript函数,使用JavaScriptCore进行OC调用JavaScript函数是很容易进行传值操做的.首先咱们须要在HTML文件建立爱你一个带有id的标签以及一个JavaScript函数.代码以下所示.
<b id="label">须要改变的标签</b>
<script type="text/javascript"> function labelAction(obj) { document.getElementById('label').innerHTML = obj; } </script>
而后就是OC代码中的操做了,咱们依然先须要对webview和JSContext对象进行初始化设置.这里就再也不重复的啰嗦了.
为了演示的效果,我把函数的调用放在了rightBarButtonItem的调用方法中.总体的代码以下所示.
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"改变" style:UIBarButtonItemStyleDone target:self action:@selector(changeWebTxet)];
下面就是实现方法,首先咱们要先经过JSContext对象获取到JS中的对应函数而且使用JSValue对象进行接收.而后咱们经过使用- (JSValue *)callWithArguments:(NSArray *)arguments;
进行JS函数的调用,固然了这里的JS函数没有返回值,我也就没有作接收返回值的工做.
-(void)changeWebTxet{ JSValue *labelAction = self.context[@"labelAction"]; [labelAction callWithArguments:@[@"你好,JS世界!"]]; }
咱们看一下总体的实现效果.
JavaScriptCore框架的初步试用我的感受仍是挺好的,JavaScriptCore框架上手比较简单.固然了,对JavaScript还要要有必定理解和基础的,这样学习起来更简单一些.若是有什么问题欢迎来跟骚栋探讨,最后附上本文的实现Demo.