背景:

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交互的两种方法的更多相关文章

  1. Android中H5和Native交互的两种方式

    Android中H5和Native交互的两种方式:http://www.jianshu.com/p/bcb5d8582d92 注意事项: 1.android给h5页面注入一个对象(WZApp),这个对 ...

  2. JS动态创建元素(两种方法)

    前言 创建元素有两种方法 1)将需要创建的元素,以字符串的形式拼接:找到父级元素,直接对父级元素的innnerHTML进行赋值. 2)使用Document.Element对象自带的一些函数,来实现动态 ...

  3. js判断手机端操作系统的两种方法

    //判断手机端操作系统(Andorid/IOS),并自动跳转相应下载界面 androidURL ="http://xxx/xxx.apk"; var browser = { ver ...

  4. js笔记(3)--js实现数组转置(两种方法)

      js实现数组转置   第一种方法:   <script>     window.onload=function(){     var array1=[[11,22,33,333],[4 ...

  5. JS取地址栏参数的两种方法

    第一种方法: function GetQueryString(name){ var reg = new RegExp("(^|&)"+ name +"=([^&a ...

  6. js访问对象属性的两种方法

    var obj={name:'fuuf',age:19} 第一种,用.访问 obj.name 第二种 用[]访问 obj['name']  //此时name是字符串,要加引号 注意事项 使用第二种方法 ...

  7. 【微信小程序】在js中导入第三方js或自己写的js,使用外部js中的function的两种方法 import和require的区别使用方法 【外加:使用第三方js导出的默认function的调用方法】

    如下 定义了一个外部js文件,其中有一个function import lunaCommon from '../lunaCommon.js'; var ctx = wx.getStorageSync( ...

  8. js获取url参数的两种方法

    js获取参数,在以前我都是用正在去拆分,然后获取,这种方式感觉是最简单的 方式1: function QueryString(item) { var sValue=location.search.ma ...

  9. js输出26个字母两种方法(js fromCharCode的使用)

    方法一 var character = new Array("A","B","C","D","E", ...

随机推荐

  1. Java串口通信详细解释

    前言 说到开源.恐怕非常少有人不挑大指称赞. 学生通过开源码学到了知识,程序猿通过开源类库获得了别人的成功经验及可以按时完毕手头的project,商家通过开源软件赚到了钱……,总之是皆大欢喜. 然而开 ...

  2. JavaScript中获取当前项目的绝对路径

    近期在做JavaWeb项目相关的东西,差点儿每天都遇到非常多问题,主要是由于自己对JavaWeb方面的知识不是非常清楚,尽量把自己在项目中遇到的问题都记录下来,方便以后查阅. 在我们的项目中有这种须要 ...

  3. 完整具体解释GCD系列(二)dispatch_after;dispatch_apply;dispatch_once

    原创Blog,转载请注明出处 本文阅读的过程中,如有概念不懂,请參照前专栏中之前的文章,假设还有疑惑,请留言. 这是我关于GCD专栏的地址 http://blog.csdn.net/column/de ...

  4. 【iOS开发-48】九宫格布局案例:自己主动布局、字典转模型运用、id和instancetype差别、xib反复视图运用及与nib关系

    本次九宫格案例: (1)导入app.plist和各种图片素材,方便兴许开发.实际开发中,也是如此. (2)把plist中数组导入进来. --由于本案例中app.plist终于是一个数组,数组里面是字典 ...

  5. NET 2015

    .NET 2015 英文原文:Understanding .NET 2015 Understanding 翻译为了解或理解,对于 .NET 来说,2015 年注定会更加精彩,所以标题就用了“精彩”这个 ...

  6. Java获取.properties配置文件某一项value根据key值

    public static String getProperty(String key){ InputStream in = PropertiesUtils.class.getResourceAsSt ...

  7. Net Framework中的提供的常用委托类型

    .Net Framework中的提供的常用委托类型   .Net Framework中提供有一些常用的预定义委托:Action.Func.Predicate.用到委托的时候建议尽量使用这些委托类型,而 ...

  8. Oracle 11g 客户端的安装和配置。

    原文:Oracle 11g 客户端的安装和配置. 数据库和客户端在不同的机器之上. 在安装之前,在安装Oracle数据库的服务器上导航到下面的目录. 将listener.ora和tnsnames.or ...

  9. 5. SQL Server数据库性能监控 - 当前请求

    原文:5. SQL Server数据库性能监控 - 当前请求 对于在线运行的系统,当前数据库性能监控,通常监视以下几点: (1) 是否有阻塞 (Blocking); (2) 是否有等待 (Waitin ...

  10. 快速构建Windows 8风格应用2-创建调试应用

    原文:快速构建Windows 8风格应用2-创建调试应用 本篇博文主要介绍的是创建应用时可以选择哪些模版,生成默认的Windows 8风格应用解决方案中含哪些文件,最后是如何调试Windows 8风格 ...