iOS: JS和Native交互的两种方法
背景:
UIWebView: iOS 用来展示 web 端内容的控件。
1. 核心方法:
- (NSString*)stringByEvaluatingJavaScriptFromString:(NSString *)script;
script 就是 JS 代码,返回结果为 js 执行结果。 比如一个 JS function 为
function testFunction(abc){
return abc;
};
webview 调用此 JS 代码如下:
NSString *js = @"testFunction('abc')";
NSString *result = [webView stringByEvaluatingJavaScriptFromString:js];
2. 重要回调:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
webview 每当需要去加载一个 request 就先回调这个方法,让上层决定是否 加载。一般在这里截获,进行本地的处理。
Native 调用 JS:
本质就一个方法,通过 stringByEvaluatingJavaScriptFromString,都是同步。
下面重点说说JS怎么回调Native:
1.通常方法:js修通过改doucument的loaction或者新建一个看不见的iFrame,修改它的 src,就会触发回调 webView 的 shouldStartLoadWithRequest,参数 request 的 url 就是新赋值的 location 或者 url,上层截获这个 url 的参数,对此分发即可。 这个都是异步调用的。
如 JS function:
var messagingIframe;
messagingIframe = document.createElement('iframe');
messagingIframe.style.display = 'none';
document.documentElement.appendChild(messagingIframe);
function TestIOSJS(){
messagingIframe.src = "ios/test/click";
};
当触发上面的JS时,webview会收到下面的回调:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSString *url = request.URL.absoluteString;
if([url hasSuffix:@"ios/test/click"]){
//do something you want
return NO;
}
return YES;
}
通过截获这个request的参数就可以做native需要做的事情。
有个开源的代码挺不错的,大家可以看看:https://github.com/marcuswestin/WebViewJavascriptBridge
2.通过XMLHttpRequest:
(1) Native子类化一个NSURLProtocol类,并通过[NSURLProtocol registerClass:self];把自己注册。
(2) JS function 创建一个 XMLHttpRequest 对象,然后可以设置携带的参数,设置同步或者异步,然后通过 send 发送请求。
function iOSExec(){
var execXhr = new XMLHttpRequest();
execXhr.open('HEAD', "/!test_exec?" + (+new Date()), true); //设置scheme
var vcHeaderValue = /.*\((.*)\)/.exec(navigator.userAgent)[1];
execXhr.setRequestHeader('vc', vcHeaderValue);//设置参数等
execXhr.setRequestHeader('rc', 1);
// 发起请求
execXhr.send(null);
};
(3) 因为步骤1已经把自己注册,所以每个客户端的网络请求都会请求这个类 的+(BOOL)canInitWithRequest:(NSURLRequest *)request,让此决定是否需要生成这个request。
@implementation TestURLProtocol +(void)initProtocol
{
[NSURLProtocol registerClass:self];
} +(BOOL)canInitWithRequest:(NSURLRequest *)request{
NSString *url = request.URL.absoluteString;
if([url containsString:@"!test_exec"]){
//do something
}
return NO;
}
(4) 通过获取这个request的参数,上层可以进行拦截,然后进行本地的相 关操作。
这个方法比较少用,不过能解决JS同步回调Native的方法。
这里也有一个开源库,大家可以看一下:https://github.com/apache/cordova-ios/tree/master/CordovaLib
The End.
iOS: JS和Native交互的两种方法的更多相关文章
- Android中H5和Native交互的两种方式
Android中H5和Native交互的两种方式:http://www.jianshu.com/p/bcb5d8582d92 注意事项: 1.android给h5页面注入一个对象(WZApp),这个对 ...
- JS动态创建元素(两种方法)
前言 创建元素有两种方法 1)将需要创建的元素,以字符串的形式拼接:找到父级元素,直接对父级元素的innnerHTML进行赋值. 2)使用Document.Element对象自带的一些函数,来实现动态 ...
- js判断手机端操作系统的两种方法
//判断手机端操作系统(Andorid/IOS),并自动跳转相应下载界面 androidURL ="http://xxx/xxx.apk"; var browser = { ver ...
- js笔记(3)--js实现数组转置(两种方法)
js实现数组转置 第一种方法: <script> window.onload=function(){ var array1=[[11,22,33,333],[4 ...
- JS取地址栏参数的两种方法
第一种方法: function GetQueryString(name){ var reg = new RegExp("(^|&)"+ name +"=([^&a ...
- js访问对象属性的两种方法
var obj={name:'fuuf',age:19} 第一种,用.访问 obj.name 第二种 用[]访问 obj['name'] //此时name是字符串,要加引号 注意事项 使用第二种方法 ...
- 【微信小程序】在js中导入第三方js或自己写的js,使用外部js中的function的两种方法 import和require的区别使用方法 【外加:使用第三方js导出的默认function的调用方法】
如下 定义了一个外部js文件,其中有一个function import lunaCommon from '../lunaCommon.js'; var ctx = wx.getStorageSync( ...
- js获取url参数的两种方法
js获取参数,在以前我都是用正在去拆分,然后获取,这种方式感觉是最简单的 方式1: function QueryString(item) { var sValue=location.search.ma ...
- js输出26个字母两种方法(js fromCharCode的使用)
方法一 var character = new Array("A","B","C","D","E", ...
随机推荐
- clearfix:after 清除css浮动
在写HTML代码的时候,发现在Firefox等符合W3C标准的浏览器中,如果有一个DIV作为外部容器,内部的DIV如果设置了float样式,则外部的容器DIV因为内部没有clear,导致不能被撑开.看 ...
- oracle_oracle中修改日期的显示格式
我的现在的日期格式是 ,要改成英文的需要输入一下命令: ALTER SESSION SET NLS_DATE_LANGUAGE=AMERICAN; 修改后变为: 同样也得若是英文要想 ...
- Android_显示器本身被卸载应用程序
1.经jni实现功能 //LOG宏定义 #define LOG_INFO(tag, msg) __android_log_write(ANDROID_LOG_INFO, tag, msg) #defi ...
- Redis源代码分析(二十七)--- rio制I/O包裹
I/O每个操作系统,它的一个组成部分.和I/O业务质量,在一定程度上也影响了系统的效率. 今天,我在了解了Redis中间I/O的,相同的,Redis在他自己的系统中.也封装了一个I/O层.简称RIO. ...
- 部署中遇到的问题-UWSGI(一)
假设uwsgi错误中提示 *** no app loaded. going in full dynamic mode *** 运行 [plain] view plaincopy aptitude in ...
- 互联网点对点通讯(P2P)
摘自: http://www.cnblogs.com/zhili/archive/2012/09/14/p2p_pnpr.html 很遗憾,目前看了下代码,我测试只是做到了本地p2p. [C# 网络编 ...
- IOS开发-Swift新语言初见
Safe Swift pairs increased type safety with type inference, restricts direct access to pointers, and ...
- T4模板生成不同部署环境下的配置文件
使用T4模板生成不同部署环境下的配置文件 在开发企业级应用的时候,通常会有不同的开发环境,比如有开发环境,测试环境,正式环境,生产环境等.在一份代码部署到不同环境的时候,不同环境的配置文件可能需要根据 ...
- AForge.NET 工具源码下载
AForge.NET是一个专门为开发者和研究者基于C#框架设计的,这个框架提供了不同的类库和关于类库的资源,还有很多应用程序例子,包括计算机视觉与人工智能,图像处理,神经网络,遗传算法,机器学习,机器 ...
- 在C#编程中玩转枚举,分享我的EnumHelper。
在C#编程中玩转枚举,分享我的EnumHelper. 在软件开发过程中,我们经常会为特定的场景下的特定数据定义逻辑意义.比如在用户表中,我们可能会有一个用户状态字段,该字段为整形.如果该字段的值为1则 ...