JavaScript与Objective-C之间的通信

之前自己闲着无聊写过几个套用网页的“皮包软件”,其实像这样的“皮包软件”也可以做得很高端大气的,通过WebKit实现的OC-JS Bridge,可以非常方便的实现在JS中调用OC的方法/在OC中调用JS的方法。如此一来,便可以通过web实现炫丽的UI,而通过原生API实现与本地相关的操作。

1、JS中变量在OC中的类型
通过OC-JS Bridge,变量的类型会自动进行转换,基本类型都会自动转换,如JS中的number、boolean都会转换成OC中的NSNumber类型,而String类型会自动转换成NSString类型,JS中的对象会转换成WebScriptObject对象,而相关的属性信息可以通过Key-Value的方法读取和写入,本文后面可看到相关的代码。

2、实现在OC中调用JS方法
在OC中调用JS方法是非常方便的,WebView有一个windowScriptObject属性,可以直接获得脚本对象,然后便可以调用callWebScriptMethod:withArguments将消息转发给JS中对象的方法和参数,对于简单的方法调用你也可以直接通过WebView的方法stringByEvaluatingJavaScriptFromString去执行一段JS代码,并返回字符串。示例代码:

12345678910111213141516
//在OC中的调用- (void)ocAction:(id)sender{    NSArray *args = @[@"Hello,JS!"];    id result = [[webView windowScriptObject] callWebScriptMethod:@"JSFunction" withArguments:args];    NSLog(@"%@",result);}//在JS中对应的方法function JSFunction(parameter){    //显示OC返回的值    alert(parameter);

    //返回成功的消息    return ‘Web程序已经收到消息!‘;}

3、实现JS调用OC的方法
通过设置webView的frameLoadDelegate,在– webView:didClearWindowObject:forFrame:回调方法中,指定一个本地对象(该对象实现WebScripting协议),然后JS中就可以直接调用该对象的相关方法。
OC中的代码如下:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
//该方法用于JS中调用- (WebScriptObject *)status:(WebScriptObject *)jsObject{    //将JS发过来的信息显示出来    NSString *message = [jsObject valueForKey:@"message"];    NSLog(@"%@",message);

    //返回成功的信息(WebScriptObject对象不能自己创建,所以此处复用了传入的参数)    [jsObject setValue:@"本地端已经收到消息啦!" forKey:@"message"];    return jsObject;}

#pragma mark -#pragma mark WebFrameLoadDelegate

//通过此回调,将self传递给JS环境- (void)webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)windowObject forFrame:(WebFrame *)frame{    [windowObject setValue:self forKey:@"native"];}

#pragma mark -#pragma mark WebScriptingProtocol

/* 返回是否阻止响应该方法, 返回NO即能响应该方法 */+ (BOOL)isSelectorExcludedFromWebScript:(SEL)selector{    if (selector == @selector(status:))    {        return NO;    }    return YES;}

/* 返回本地方法在JS中的名称(不实现此方法,则JS中方法名与OC中相同) */+ (NSString *)webScriptNameForSelector:(SEL)sel{    if (sel == @selector(status:))    {        return @"ocMethod";    }    return nil;}

JS中代码如下:

123456789101112
function CallNative(){    if (native)    {        //将消息组装成对象发给OC        var parameter = {‘message‘:‘Hello,Objective-C!‘};        var result = native.ocMethod(parameter);

        //显示OC返回的结果        alert(result[‘message‘]);    }}

相关的示例代码可以参见Apple的CallJS这个Demo,也可以直接下载我写的Demo:OCJS_Bridge.zip

时间: 2024-08-05 07:00:56

JavaScript与Objective-C之间的通信的相关文章

【JavaScript】父子页面之间跨域通信的方法

由于同源策略的限制,JavaScript跨域的问题,一直是一个比较棘手的问题,为了解决页面之间的跨域通信,大家煞费苦心,研究了各种跨域方案.之前也有小网同学分享过一篇“跨域,不再纠结” 开始照着尝试时还是有些不够明白的地方,深入了解之后,这里给大家补充一点更具体的做法. 先来看看哪些情况下才存在跨域的问题: 其中编号6.7两种情况同属于主域名相同的情况,可以设置domain来解决问题,今天就不讨论这种情况了. 对于其他跨域通信的问题,我想又可以分成两类: 其一(第一种情况)是a.com下面的a.

JS观察者设计模式:实现iframe之间快捷通信

观察者设计模式又称订阅发布模式,在JS中我们习惯叫做广播模式,当多个对象监听一个通道时,只要发布者向该通道发布命令,订阅者都可以收到该命令,然后执行响应的逻辑.今天我们要实现的就是通过观察者设计模式,实现iframe之间的通信. 一.top对象 一般的JS书里都会在讲框架集的时候讲top,这会让人误解,认为top对象只是代表框架集,其实top的含义应该是说浏览器直接包含的那一个页面对象,也就是说如果你有一个页面被其他页面以iframe的方式包含了,无论包含的层级是什么,都可以用top访问最外层的

浅谈两种方法实现浏览器内多个标签页之间的通信

调用localstorge.cookies等本地存储方式. 方法一: localstorge在一个标签页里被添加.修改或删除时,都会触发一个storage事件,通过在另一个标签页里监听storage事件,即可得到localstorge存储的值,实现不同标签页之间的通信. <input id="name"> <input type="button" id="btn" value="提交"> <scr

(转)如何实现同一浏览器多个标签页之间的通信(二)——cookie+setInterval

二.cookie (1)cookie是什么? HTTP Cookie,通常直接叫做cookie,最初是在客户端用于存储回话信息的.该标准要求服务器对任意HTTP请求发送Set-Cookie HTTP头作为响应的一部分,其中包含回话信息.浏览器会存储这样的回话信息,并在这之后,通过每个请求添加Cookie HTTP头将信息发回服务器. (2)cookie怎么用? 在JavaScript中,cookie的接口即document.cookie不太友好,可以自己封装相应的接口. 基本cookie操作:读

Linux操作系统 进程之间的通信

进程之间的通信 预备知识: 1.用户态和内核态,当一个进程在执行用户自己的代码时处于用户运行态(用户态):当一个进程因为系统调用陷入内核代码中执行时处于内核运行态(内核态). 2.进程之间的通信(Inter Processs Communication-IPC)实现机制有:管道.消息队列.信号值.信号.共享内存.共享映射文件.套接字等. 3.及时通信:信号(类似中断):非及时通信:共享内存.邮箱.管道.套接字. 4.常见的信号:终止信号.定时器信号.用户自定义信号等 5.信号:用户.系统或者进程

线程之间的通信

1.1.线程之间的通信方法 多个线程在处理统一资源,但是任务却不同,这时候就需要线程间通信.    等待/唤醒机制涉及的方法:    1. wait():让线程处于冻结状态,被wait的线程会被存储到线程池中.    2. notify():唤醒线程池中的一个线程(任何一个都有可能).    3. notifyAll():唤醒线程池中的所有线程.  备注    1.这些方法都必须定义在同步中,因为这些方法是用于操作线程状态的方法.    2.必须要明确到底操作的是哪个锁上的线程!    3.wa

Android - Fragment (三)不同Fragment之间的通信

在Fragment的java文件中,可以使用getActivity()来获得调用它的activity, 然后再找到另一个Fragment,进行通信 getActivity().getFragmentManager().findFragmentById(R.id.fragment_list); 但这样做耦合度太高,不方便后续的修改操作 Fragment与其附着的Activity之间的通信,都应该由Activity来完成 不能是多个Fragment之间直接通信 Fragment与其附着的Activi

两个页面之间的通信

今天要给大家说的是两个不同页面之间的通信,通过一个拖拽demo来模拟: 首先,写好基础的拖拽代码: <script> window.onload = function() { var oDiv = document.getElementById('div'); oDiv.onmousedown = function(ev) { var ev = window.event || ev; var disX = ev.clientX - oDiv.offsetLeft; var disY = ev.

多线程之间的通信实例讲解

                 多线程之间的通信实例讲解对于线程来说,说白了,就是一个函数,如果大家对于这章函数都有理解,那我对于操作系统,线程和进程间的通信会有一个新的认识!接下来我会对每一行代码进行注释,在此过程中,大家也可以对c语言有一个崭新的认识. 第一个函数,创建两个线程. #include <stdio.h>#include <pthread.h>    这个头函数要包含,因为我们后续用的函数都是系统调用,因此需要申请头函数   这样在编译的时候,就可以找到此函数的源

利用DNode实现php和nodejs之间的通信

一,安装DNode, 1, for nodejs, 执行 $ sudo npm install dnode 2, for php, 利用composer来安装DNode php 执行下列语句下载composer $ wget http://getcomposer.org/composer.phar 创建一个文件composer.json,然后填入如下语句, {     "require": {         "dnode/dnode": "0.2.0&q