UIWebView-JSContext实现OC与JS交互
2016-05-20 17:48
633 查看
最近的项目中native APP提供基本的功能,部分业务放在h5中,为了提升交互体验,保证native中操作和webview中一致,需要提供Objective-C与javeScript的交互接口,也正因为项目支持版本IOS7,而IOS7以后使用javascriptcore.framework和h5的通信也相对以前简单了很多,不需要定义那么多的url shcema,可以直接通过javascriptcore完成Objective-C与javeScript的交互。
1.webView中JSContext的获取
使用 javascriptcore交互的核心是通过从webview中获取到当前的JSContext,在JSContext中执行对应的操作,一般情况下可以通过以下接口获取到当前页面的JSContext
如果webview中进行了不同的页面切换,就需要在每次完成新的页面加载后,刷新当前记录的JSContext,确保JSContext实时有效。
2.Objective-C调用javeScript
这部分比较简单,第一种方案可以直接使用
调用javeScript提供的接口,传参。
第二种方案,使用JSContext获取对应的接口后,使用
或
- (JSValue )evaluateScript:(NSString )script;
3.javeScript调用Objective-C
这个需要使用javascriptcore提供的JSExport,在Objective-C中实现该protocol的方法,就可以在javeScript使用到的接口了。JSExport相当于跨语言提供的protocol。
首先将在当前JSContext进行类注册
存在的问题
正如第一步中刷新JSContext一样,在不同页面进行刷新后的时候,都需要将OC提供给JS的方法进行注册,确保当前JS环境中提供的接口有效。
1.webView中JSContext的获取
使用 javascriptcore交互的核心是通过从webview中获取到当前的JSContext,在JSContext中执行对应的操作,一般情况下可以通过以下接口获取到当前页面的JSContext
_defaultContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
如果webview中进行了不同的页面切换,就需要在每次完成新的页面加载后,刷新当前记录的JSContext,确保JSContext实时有效。
-(void)webViewDidFinishLoad:(UIWebView *)webView { //网页加载完成调用此方法 _defaultContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; }
2.Objective-C调用javeScript
这部分比较简单,第一种方案可以直接使用
- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;
调用javeScript提供的接口,传参。
//假设JS中提供login函数 [webView stringByEvaluatingJavaScriptFromString:@"login('username','password')"];
第二种方案,使用JSContext获取对应的接口后,使用
- (JSValue *)callWithArguments:(NSArray *)arguments;
或
- (JSValue )evaluateScript:(NSString )script;
[_defaultContext evaluateScript:@"login('username','password')"];
//通过 JSContext 调用JS 方法,执行 JSValue *JSfunc =_defaultContext[@"login"]; [JSfunc callWithArguments:@[@'username',@'password']];
3.javeScript调用Objective-C
这个需要使用javascriptcore提供的JSExport,在Objective-C中实现该protocol的方法,就可以在javeScript使用到的接口了。JSExport相当于跨语言提供的protocol。
#include <JavaScriptCore/JavaScriptCore.h> // Protocol to list bindings @protocol JSBridgeExport <JSExport> //为webview中提供与native一致的提示功能 - (void)showTip:(NSString *)tip; @end @interface JSBridge : NSObject <JSBridgeExport> @end @implementation JSBridge - (void)showTip:(NSString *)tip{ [TopWindow makeToast:tip]; } @end
首先将在当前JSContext进行类注册
_defaultContext[@"jsbridge"] = [[JSBridge alloc]init];,然后就可以在JS中通过jsbridge调用OC提供的方法接口了。
[_defaultContext evaluateScript:@"jsbridge.showTip(\"this is a tip from webview\")"];
存在的问题
正如第一步中刷新JSContext一样,在不同页面进行刷新后的时候,都需要将OC提供给JS的方法进行注册,确保当前JS环境中提供的接口有效。
-(void)webViewDidFinishLoad:(UIWebView *)webView { //网页加载完成调用此方法 //刷新当前记录JSContext,刷新接口 _defaultContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; _defaultContext[@"jsbridge"] = [[JSBridge alloc]init]; }
相关文章推荐
- JQuery1——基础($对象,选择器,对象转换)
- Android学习笔记(二九):嵌入浏览器
- Android java 与 javascript互访(相互调用)的方法例子
- JavaScript演示排序算法
- javascript实现10进制转为N进制数
- 最后一次说说闭包
- Ajax
- 2019年开发人员应该学习的8个JavaScript框架
- HTML中的script标签研究
- 对一个分号引发的错误研究
- 异步流程控制:7 行代码学会 co 模块
- ES6 走马观花(ECMAScript2015 新特性)
- JavaScript拆分字符串时产生空字符的原因
- Canvas 在高清屏下绘制图片变模糊的解决方法
- Redux系列02:一个炒鸡简单的react+redux例子
- JavaScript 各种遍历方式详解
- call/apply/bind 的理解与实例分享