iOS中使用JavaScriptCore实现Objective-C和JavaScript的相互调用
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了iOS中使用JavaScriptCore实现Objective-C和JavaScript的相互调用,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4553字,纯文字阅读大概需要7分钟。
内容图文
最近看了一个对Github上面编程语言使用统计的排行榜,JavaScript真可以说是一枝独秀,很难想象20年前,这个语言只是浏览器中的装饰性语言,能做的事情也就是一点特效或者检查一下要提交给服务器的表单是否满足要求。今天的JavaScript已经是一个全栈语言,从客户端到服务器无所不在。很多编程语言都提供了跟JavaScript进行交互的接口,这一点在iOS开发中也不例外。
??iOS7以前,在App中调用JavaScript的方式只有一种,就是通过UIWebView对象的stringByEvaluatingJavaScriptFromString:方法。由于UIWebView中包含了CSS渲染引擎和JavaScript执行引擎(说白了就是微型一个浏览器),因此这个方法可以让UIWebView通过它的JavaScript运行时环境执行JavaScript代码,但是能做的事情非常有限,我们可以先看看下面的例子。
- (void)webViewDidFinishLoad:(UIWebView *)webView {
// 获得UIWebView中加载页面的标题NSString *title = [webView stringByEvaluatingJavaScriptFromString:
@"document.title"];
NSLog(@"%@", title);
// 获得UIWebView中加载页面的链接地址NSString *urlStr = [webView stringByEvaluatingJavaScriptFromString:
@"location.href"];
NSLog(@"%@", urlStr);
}
??从iOS7开始,我们可以使用JavaScriptCore框架来让我们的Objective-C代码和JavaScript进行深度交互,简单的说我们可以在Objective-C代码中访问JavaScript中的变量或调用JavaScript的函数,也可以JavaScript中使用Objective-C的对象和方法。我们可以先看一个简单的例子。
先加入JavaScriptCore的头文件。
#import <JavaScriptCore/JavaScriptCore.h>
在Objective-C中使用JavaScript的正则表达式验证字符串。
// 创建JavaScript执行环境(上下文)
JSContext *context = [[JSContext alloc] init];
NSString *funCode =
@"var isValidNumber = function(phone) {"" var phonePattern = /^1[34578]\\d{9}$/;"" return phone.match(phonePattern);""};";
// 执行上面的JavaScript代码
[context evaluateScript:funCode];
// 获得isValidNumber函数并传参调用
JSValue *jsFunction = context[@"isValidNumber"];
JSValue *value1 = [jsFunction callWithArguments:@[ @"13012345678" ]];
NSLog(@"%@", [value1 toBool]? @"有效": @"无效"); // 有效
JSValue *value2 = [jsFunction callWithArguments:@[ @"12345678899" ]];
NSLog(@"%@", [value2 toBool]? @"有效": @"无效"); // 无效
在Objective-C中调用JavaScript函数求阶乘。
// 创建JavaScript执行环境(上下文)
JSContext *context = [[JSContext alloc] init];
// 可以将一个block传给JavaScript上下文// 它会被转换成一个JavaScript中的函数
context[@"factorial"] = ^(int x) {
double result = 1.0;
for (; x > 1; x--) {
result *= x;
}
return result;
};
// 执行求阶乘的函数
[context evaluateScript:@"var num = factorial(5);"];
JSValue *num = context[@"num"];
NSLog(@"5! = %@", num); // 5! = 120
??JavaScript和Objective-C中类型的对应关系如下表所示:
Objective-C类型 | JavaScript类型 |
---|---|
nil | undefined |
NSNull | null |
NSString | string |
NSNumber | number, boolean |
NSDictionary | Object object |
NSArray | Array object |
NSDate | Date object |
NSBlock | Function object |
id | Wrapper object |
Class | Constructor object |
??
??再来看一个例子。我们在根视图控制器中放置一个按钮,点击后会导航到下一个视图控制器,其中有一个UIWebView加载了一个网页,页面中有一颗按钮,我们希望点击按钮后导航到上一个视图控制器,要做到这一点,就需要在JavaScript中访问Objective-C对象和方法。
页面的代码:
<!doctype html>
<html>
<head>
<metacharset="utf-8" />
<title>测试页面</title><styletype="text/css">#backButton{
display: inline-block;
width:50px; height:30px;
}</style></head><body><buttonid="backButton">返回</button><scripttype="text/javascript">var btn = document.getElementById("backButton");
var cb = function() {
window.alert(‘Hello‘);
};
btn.addEventListener(‘click‘, cb, false);
</script></body></html>
第二个视图控制器的代码:
#import "ViewController.h"
#import <JavaScriptCore/JavaScriptCore.h>
@protocol
MyProtocol <JSExport>
- (void) letsGoBack;
@end@interfaceSecondViewController : ViewController <MyProtocol>@end
@interface
SecondViewController () <UIWebViewDelegate>
@property (weak, nonatomic) IBOutletUIWebView *myWebViw;
@end@implementationSecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
[_myWebViw loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:
@"http://localhost:8080/myweb/test.html"]]];
_myWebViw.delegate = self;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
// 通过UIWebView获得网页中的JavaScript执行环境
JSContext *context = [webView valueForKeyPath:
@"documentView.webView.mainFrame.javaScriptContext"];
// 设置处理异常的block回调
[context setExceptionHandler:^(JSContext *ctx, JSValue *value) {
NSLog(@"error: %@", value);
}];
context[@"callBackObj"] = self;
// 下面的代码移除了按钮原先绑定的事件回调重新绑定返回上一个视图控制器的代码NSString *code =
@"var btn = document.getElementById(‘backButton‘);""btn.removeEventListener(‘click‘, cb);""btn.addEventListener(‘click‘, function() {"" callBackObj.letsGoBack();""});";
[context evaluateScript:code];
}
// 实现协议中的方法
- (void) letsGoBack {
// 必须回到主线程刷新用户界面dispatch_async(dispatch_get_main_queue(), ^{
[self.navigationController popViewControllerAnimated:YES];
});
}
@end
??可以在Github上下载到上面例子的完整代码。
原文:http://blog.csdn.net/jackfrued/article/details/50781898
内容总结
以上是互联网集市为您收集整理的iOS中使用JavaScriptCore实现Objective-C和JavaScript的相互调用全部内容,希望文章能够帮你解决iOS中使用JavaScriptCore实现Objective-C和JavaScript的相互调用所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。