在上一篇文章中,OC 和 JS 交互的核心是方法的返回值。
也就是说,OC 如果需要 JS 的数据,就必须调用 JS 的函数,并获得返回值。
JS 要获得 OC 的参数,就需要调用 OC 的方法,并获得返回值。
这种交互是建立在方法的返回值上的。
但方法/函数不只有返回值,方法/函数还有参数。
被动的等待对方调用自己的方法,并通过参数的方式获取对方的数据。
上一篇使用的是方法/函数的返回值获取对方的数据,这是一种主动的行为。
而使用方法参数的方式,则是被动的等待对方调用自己的方法-传入参数,并获取数据。
场景
需要完成的目标
- OC 的控件里,输入信息,然后通过 OC 把数据传递到 H5。
- H5 里面有一个 Ajax 请求,当请求返回数据之后,把数据传递到 OC 的 tableView 上并显示。
特点:
因为 H5 不知道 OC 什么时候用户会输入完信息。所以只能被动的等待。
因为 OC 不知道 H5 的 ajax 请求什么时候返回,所以只能被动的等待。
代码
HTML 文件
<html>
<head>
<title></title>
<meta charset="UTF-8">
<script type="text/javascript" src="jquery-3.3.1.min.js"></script>
</head>
<body>
<span>这两个文本框的内容是 OC 的参数传递过来的。<span></span><br />
用户名:<input type="text" id="username" /><br />
手机号码:<input type="text" id="userPhone"/><br />
<br /><br /><br /><br /><br /><br />
<button id="ajaxBtn">异步 ajax 请求,数据请求回来之后,需要传递到 OC</button>
</body>
</html>
<script type="text/javascript">
// 等待 OC 的调用,并将 OC 的NSDictionary 传递成 JS 的 data。
function setUserNameAndUserPhone(data) {
document.getElementById("username").value = data.userName;
document.getElementById("userPhone").value = data.userPhone;
}
document.getElementById("ajaxBtn").onclick = function() {
$.ajax({
url:"http://127.0.0.1/apps.json",
success : function(result) {
// JS 主动的调用 OC 的方法,OC 被动的等待 Ajax 数据返回。
showAjaxData(result);
}
});
}
</script>
目标1:当用于在 OC 中输入完毕信息之后,传递到 H5
分析:H5 被动的等待 OC 调用自己的方法。
H5 JS 赋值函数,被动等待
// 等待 OC 的调用,并将 OC 的NSDictionary 传递成 JS 的 data。
function setUserNameAndUserPhone(data) {
document.getElementById("username").value = data.userName;
document.getElementById("userPhone").value = data.userPhone;
}
OC 在用户输入完毕,并点击 UIButton 之后,调用 JS 的函数,传递参数,最终将 OC 的数据传递过去。
// 调用 JS 的函数并传递参数,参数最终就流向了 JS。
- (IBAction)invokeJsFunc:(id)sender {
JSValue *jsFunc = _jsContext[@"setUserNameAndUserPhone"];
NSDictionary *params = @{
@"userName" : self.userNameTxt.text,
@"userPhone" : self.userPhoneTxt.text
};
[jsFunc callWithArguments:@[params]];
}
运行截图:
目标2:H5有一个 ajax 请求,当请求的数据返回值时,调用 OC 的方法,传递数据
首先,需要把接受 Ajax 数据的 OC 方法注册到当前JS上下文。
_jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
_jsContext.exceptionHandler = ^(JSContext *context, JSValue *exception) {
NSLog(@"%@",@"获取 WebView JS 执行环境失败了!");
};
__weak typeof(self) weakSelf = self;
_jsContext[@"showAjaxData"] = ^(NSArray *ajaxData) {
__strong typeof(weakSelf) sself = weakSelf;
// NSLog(@"%@",ajaxData);
sself.ajaxModelList = [ajaxData modelListWithClass:[AjaxModel class]].mutableCopy;
NSLog(@"%@",sself.ajaxModelList.firstObject);
dispatch_async(dispatch_get_main_queue(), ^{
// OC 注入到 JS 中的方法,默认都是在子线程调用的。
[sself.tableView reloadData];
});
};
然后再 H5 的 Ajax 请求 success 之后调用 OC 的方法把服务器返回的数据从 JS 传到 OC。
document.getElementById("ajaxBtn").onclick = function() {
$.ajax({
url:"http://127.0.0.1/apps.json",
success : function(result) {
// JS 主动的调用 OC 的方法,OC 被动的等待 Ajax 数据返回。
showAjaxData(result);
}
});
}
当 OC 拿到用户数据之后,刷新表格。即可显示服务器传递回来的数据了。
运行效果:
最后总结:
- OC 和 H5 通过方法/函数传递数据有两种方式:返回值、参数。
- 利用返回值的时候,都是主动的调用对方的函数以获取返回值。
- 利用参数的时候,都是被动的等待对方调用自己。(常见的就是 H5 的 ajax 数据返回,OC 只能被动的等待)。