使用JS和OC交互(JavaScriptCore)
JavaScriptCore定义
JavaScriptCore.framework :iOS7 中新加入的框架,用来处理JavaScript。JavaScriptCore 是苹果 Safari 浏览器的 JavaScript 引擎,JavaScriptCor在 OS X 平台上很早就存在的,而在 iOS 平台,直到IOS7才对外开放,并提供了 Objective-C 的接口。
相关类
JSContext:
一个Contet就是一个JS的执行环境,也叫作用域.每个JsValue都和JSContext关联的,并且强引用context.
JSValue:
JS对象在JSVirtualMachine中的一个强引用,其实就是Hybird对象.OC和JS对象之间的转化也是通过JSValue
JSManagedValue:
JS和OC对象的内存管理辅助对象。由于JS内存管理是垃圾回收,并且JS中的对象都是强引用,而OC是引用计数。如果双方相互引用,势必会造成循环引用,而导致内存泄露。我们可以用JSManagedValue保存JSValue来避免。
JSVirtualMachine:
JS运行的虚拟机,有独立的堆空间和垃圾回收机制。
JSExport
一个协议,如果JS对象想直接调用OC对象里面的方法和属性,那么这个OC对象只要实现这个JSExport协议就可以了。
实现
使用OC来调用JS的方法
1.js部分
//求一个数的阶乘
var factorial = function(n){
if( n < 0){
return;
}
if(n === 1){
return 1;
}
return n * factorial(n-1);
}
2.OC部分
- (void)factorial:(NSNumber *)n{
NSString *jsPath =[[NSBundle mainBundle] pathForResource:@"main" ofType:@"js"];
NSString *jsStr =[NSString stringWithContentsOfFile:jsPath encoding:NSUTF8StringEncoding error:nil];
//初始化Js环境
JSContext *context = [[JSContext alloc]init];
[context evaluateScript:jsStr];
//获取JS方法
JSValue *function = context[@"factorial"];
//运行方法传递参数
JSValue *result = [function callWithArguments:@[n]];
NSLog(@"result:%d",[result toInt32]);
}
在WebView中的使用
一: 使用JSExport实现OC和JS的交互
1.html代码部分:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
</head>
<body>
<h1>JavaScriptCore</h1>
<div>
<!-- 创建一个分享的按钮 --!>
<input type="button" value="share" onclick="JSShare()">
</div>
<script>
function JSShare() {
<!-- 创建分享数据 --!>
var shareContent = JSON.stringify({"title": "JavaScriptCore", "desc": "使用JSExport协议进行交互", "shareUrl": "www.cjzkw.cn"});
alert(shareContent);
<!-- ricky就是相当于桥梁,链接oc和js--!>
ricky.share(shareContent);
}
<!-- 使用oc调用js方法 --!>
function showAlert(message){
alert(message);
}
<!-- JS调用oc成功后的回调 --!>
var shareSuccessCallback = function(){
alert('success');
}
</script>
</body>
- OC部分
#import "ViewController.h"
#import <JavaScriptCore/JavaScriptCore.h>
//先要使用JS调用OC的方法,需要写一个遵循JSExport的协议和协议方法.
@protocol JSObjectDelegate <JSExport>
- (void)share:(NSString *)shareContent;
@end
//在ViewController需要遵循上面我们书写的协议.
@interface ViewController ()<UIWebViewDelegate,JSObjectDelegate>
@property(nonatomic,strong)UIWebView *webview;
@property (strong, nonatomic) JSContext * context;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.webview = [[UIWebView alloc]initWithFrame:self.view.bounds];
self.webview.delegate = self;
NSURL *url = [[NSBundle mainBundle] URLForResource:@"mainhtml" withExtension:@"html"];
[self.webview loadRequest:[NSURLRequest requestWithURL:url]];
[self.view addSubview:self.webview];
}
-(void)webViewDidFinishLoad:(UIWebView *)webView{
//获取webView的JSContext
_context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
//ricky和html里面的相一致,相当于桥接,用来实现JS和OC的交互
_context[@"ricky"] = self;
//异常处理,
_context.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue){
context.exception = exceptionValue;
NSLog(@"异常信息:%@", exceptionValue);
};
}
//实现协议方法,就是js需要调用的OC的方法.
- (void)share:(NSString *)shareContent {
//shareContent就是JS传过来的需要分享的数据
NSLog(@"share:%@", shareContent);
// 分享成功后,使用OC来调用JS成功回调方法
JSValue *shareCallback = self.context[@"shareCallback"];
//nil:表示该shareCallback回调方法没有参数.
[shareCallback callWithArguments:nil];
}
二. 使用Blcok进行的交互
1.html部分:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
</head>
<body>
<h1>OC和JS的交互Block方式</h1>
<div>
<input type="button" value="JsToOcShare" onclick="callShare(shareContent)">
</div>
<script>
var shareContent = JSON.stringify({"title":"分享", "desc":"分享内容", "shareUrl":"http://www.jianshu.com/users/774b1d5616a7/latest_articles"});
//js向OC传递参数的方法
function callShare(share) {
}
// OC调JS message为传递的参数
function showAlert(message){
alert(message);
}
</script>
</body>
</html>
- OC部分
-(void)showAlter{
NSString *jsStr = @"showAlert('oc js交互成功')";
[_context evaluateScript:jsStr];
}
-(void)webViewDidFinishLoad:(UIWebView *)webView{
_context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
//OC和JS交互
[self showAlter];
//JS和OC交互
// __weak typeof (self)weakSelf = self;
_context[@"callShare"] = ^(id obj){
NSLog(@"%@",obj);
};
//异常处理
_context.exceptionHandler = ^(JSContext *context,JSValue *exceptionValue){
context.exception = exceptionValue;
NSLog(@"异常信息:%@", exceptionValue);
};
}
参考:
http://blog.csdn.net/lizhongfu2013/article/details/9232129
http://www.zuimoban.com/jiaocheng/ios/2016/0427/7091.html
网友评论