简述
网络上现在存在很多关于OC与JS交互的资料,最近做项目中需要,这边整理下来,以方便自己和大家查阅。
与同事沟通,我发现了OC与JS交互可以有很多种方式,这里简单列出两种
1. Apple 系统原生的API
2. 第三方 WebViewJavaScriptBrige
这里就不详细展开 WebViewJavaScriptBrige,有需要的朋友可以 百度 一下。
系统原生API
A. OC 调用 JS 方法
相关API:
- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;
苹果注解:
主观见解:
调用的形式是 [UIWebView实例 stringByEvaluatingJavaScriptFromString:@" JS函数调用语句 "];
B. JS 调用 OC 方法
相关API:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
苹果注解:
主观见解:
利用 DOM中的 iframe元素,创建一个内容为空的页面,然后以 src 作为 Tag 来传递约定好的信息。
实例讲解
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试OC</title>
<script type="text/javascript">
function ocCallTouch(){
alert("I'm touched");
}
function ocCallTouchAndPara(greeting){
alert(greeting);
}
function jsCallObjectiveC() {
var iFrame;
iFrame = document.createElement("iframe");
iFrame.setAttribute("src","ios://theJumpLabel");
iFrame.setAttribute("style","display:none");
iFrame.setAttribute("height","0px");
iFrame.setAttribute("width","0px");
iFrame.setAttribute("frameborder","0");
document.body.appendChild(iFrame);
iFrame.parentNode.removeChild(iFrame);
iFrame = null;
}
</script>
</head>
<body>
<input type="submit" value="提交" οnclick="jsCallObjectiveC()">
</body>
</html>
.m 文件
#import "RootViewController.h"
@interface RootViewController ()<UIWebViewDelegate>
@property (weak, nonatomic) IBOutlet UIWebView *displayWebView;
@end
@implementation RootViewController
- (void)viewDidLoad {
[super viewDidLoad];
_displayWebView.delegate = self;
[_displayWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"]]]];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"ocCallJSNo" style:UIBarButtonItemStylePlain target:self action:@selector(ocCallJSNoPara)];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"ocCallJS" style:UIBarButtonItemStylePlain target:self action:@selector(ocCallJSHavaPara)];
}
/**
* OC调用JS代码,无参数
*/
- (void)ocCallJSNoPara {
[_displayWebView stringByEvaluatingJavaScriptFromString:@"ocCallTouch()"];
}
/**
* OC调用JS代码,有参数
*/
- (void)ocCallJSHavaPara {
// 后面()内部的参数,
[_displayWebView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"ocCallTouchAndPara('%@')",@"Hello"]];
}
/**
* UIWebView回调函数,主要作为JS调用OC时的一种标识
*/
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSString *urlString = request.URL.absoluteString;
if ([urlString isEqualToString:@"ios://theJumpLabel"]) {
// 对应标识,进行OC这边的处理, OC暂存
NSLog(@"Do some Task!");
}
return YES;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
// 将 OC暂存的东西进行任务处理
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
1. 为了方便不了解 HTML5的朋友,这里将JS代码 全部放入 head 标签中。 function 代表函数,() 代表无参数,(greeting)代表有一个参数为greeting,这里不需要加参数类型
2. iFrame 元素 可以把它看成另外一个页面,只是这里 将它的宽高设置为0,然后 发送完请求后,就从父类中删除了它。
3. 根据亲自实践,如果把 JS调用OC中返回的处理方法写在shouldStartLoadWithRequest 中,返回事件执行看不出效果,所以最好还是 暂存,然后放入webViewDidFinishLoad 中进行相关处理。
4. 网上的信息指出,HTML 中嵌套的js、css文件不要带路径,安装之后在同一目录下(iOS打包之后,执行环境中资源文件在同一目录下)。
鄙人文笔不太好,如看不懂,请看下方对应资料原创者的文章。
资料整理自
1. http://blog.csdn.net/jwzhangjie/article/details/46823721