iOS中实现js与oc的交互,目前网上也有不少流行的开源解决方案;

如:react native

当然一些轻量级的任务使用系统提供的UIWebView 以及JavaScriptCore.framework 里面提供的api就能快速满足的。

方式一:iOS6上使用UIWebView 拦截url方式

以下是演示的js和oc端的代码

<html>
<head><title>JAAndOC1</title></head>
<script>
function sdkhi()
{
alert("hello world!");
} function sdkhito(name)
{
alert("hello to "+name);
} </script>
<body> <h1>hello world</h1>
<h1>hello world</h1>
<h1>hello world</h1>
<h1>hello world</h1> <h1><a href="TCSDK://START?name=cc&age=18&phone=10086">START</a></h1>
<h1><a href="javascript:sdkhi()">SDKHI</a></h1> </body> </html>
@interface ViewController ()<UIWebViewDelegate>
{
UIWebView *theWeb;
}
@end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; theWeb = [[UIWebView alloc]initWithFrame:self.view.bounds];
theWeb.scalesPageToFit = YES;
theWeb.delegate = self;
[self.view addSubview:theWeb]; //本示例方法适用于iOS 6 + NSURL *reqUrl = [NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"js1.html" ofType:nil]];
[theWeb loadRequest:[NSURLRequest requestWithURL:reqUrl]]; UIButton *clickBtn = [UIButton buttonWithType:UIButtonTypeCustom];
clickBtn.frame = CGRectMake(, , , );
[clickBtn setTitle:@"clisk" forState:];
[clickBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
[self.view addSubview:clickBtn];
[clickBtn addTarget:self action:@selector(clickToCloseAlert) forControlEvents:UIControlEventTouchUpInside]; } //OC调JS 并传参数
- (void)clickToCloseAlert
{
//在弹出的alert中可能会有来自 xxx.html 字样 (百度去掉)
[theWeb stringByEvaluatingJavaScriptFromString:@"sdkhito('cc')"];
} //JS 调 OC 并传参数
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{ //访问如下自定义协议连接
//request.URL tcsdk://START?name=cc&age=18&phone=10086
//request.URL.scheme tcsdk 取出协议
//request.URL.host START 取出host
//request.URL.query name=cc&age=18&phone=10086 取出参数
NSLog(@"%@",request.URL);
NSLog(@"%@",request.URL.scheme); return YES;
}

1. OC 调用js代码主要通过如下接口

[theWeb stringByEvaluatingJavaScriptFromString:@"sdkhito('cc')"];

流程:iOS的UIWebView 加载 包含js的网页;在js中定义好函数接口;

然后在oc上就可以通过上面接口直接调用的;

2. JS 调用OC 主要通过UIWebView的代理方法shouldStartLoadWithRequest 拦截URL

//JS 调 OC 并传参数

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType

{

//访问如下自定义协议连接

//request.URL   tcsdk://START?name=cc&age=18&phone=10086

//request.URL.scheme   tcsdk 取出协议

//request.URL.host     START 取出host

//request.URL.query name=cc&age=18&phone=10086  取出参数

NSLog(@"%@",request.URL);

NSLog(@"%@",request.URL.scheme);

return YES;

}

流程:iOS UIWebView 加载包含js的网页;在网页中用<a> 标签名其他跳转方式改变url的操作;

然后在代理中通过拆分url的结构,分别取出协议,host,参数等;来达到js调用oc方法的的目的。

  问题:通过url传参有限制

方式二:iOS7之后使用 JavaScriptCore.framework

该框架提供完整的js运行环境,在处理oc与js的交互中非常的方法;

如下测试代码

<html>
<head><title>JAAndOC2</title></head>
<script> //以下方法由oc 调用 js
function sdkhi3TO(name)
{
alert("hello world2!"+name);
} function sdkhi2()
{
alert("hello world2!");
} function sdkhito(name)
{
alert("hello to "+name);
} </script>
<body> <h1>hello world</h1>
<h1>hello world</h1>
<h1>hello world</h1>
<h1>hello world</h1> <h1><a href="TCSDK://START?name=cc&age=18&phone=10086">START</a></h1>
<h1><a href="javascript:sdkhi2()">SDKHI</a></h1> <!-- 以下由js 调用oc 的方法 -->
<h1><a href="javascript:ocsayhi('abc')">OCHI</a></h1>
<h1><a href="javascript:alert(pl.fullyName())">OCHI</a></h1> </body> </html>
#import "ViewController.h"
#import <JavaScriptCore/JavaScriptCore.h>
#import "Person.h" @interface ViewController ()<UIWebViewDelegate>
{
UIWebView *theWeb;
JSContext *jsCXT;
} @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
//以下使用javascriptcore.framewordk //适用于iOS7.0 theWeb = [[UIWebView alloc]initWithFrame:self.view.bounds];
theWeb.scalesPageToFit = YES;
theWeb.delegate = self;
[self.view addSubview:theWeb]; NSURL *reqUrl = [NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"js2.html" ofType:nil]];
[theWeb loadRequest:[NSURLRequest requestWithURL:reqUrl]]; } - (void)webViewDidFinishLoad:(UIWebView *)webView
{
//使用webview的js执行环境
jsCXT = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; //异常处理
jsCXT.exceptionHandler =
^(JSContext *context, JSValue *exceptionValue)
{
context.exception = exceptionValue;
NSLog(@"%@", exceptionValue);
}; //OC 调用JS
//[jsCXT[@"sdkhi2"] callWithArguments:nil];
//sdkhito
//[jsCXT[@"sdkhito"] callWithArguments:@[@"aa"]]; //注册一个方法由js调用
jsCXT[@"ocsayhi"] = ^(NSString *name) {
NSLog(@"say hi to %@",name);
}; Person *pp = [[Person alloc]init];
pp.firstName = @"cc";
pp.lastName = @"j";
pp.site = @"baidu.com";
jsCXT[@"pl"] = pp; [jsCXT evaluateScript:@"alert(pl.fullyName())"]; }
#import <Foundation/Foundation.h>
#import <JavaScriptCore/JavaScriptCore.h>
@protocol PersonPtl <JSExport> @property (nonatomic,copy)NSString *site;
/**
对于多参数的方法,JavaScriptCore的转换方式将Objective-C的方法每个部分都合并在一起,冒号后的字母变为大写并移除冒号。比如下边协议中的方法,在JavaScript调用就是:doFooWithBar(foo, bar); **/
- (NSString *)fullyName; @end @interface Person : NSObject<PersonPtl> @property (nonatomic, copy) NSString *firstName;
@property (nonatomic, copy) NSString *lastName; @end
#import "Person.h"

@implementation Person

@synthesize site;

- (NSString *)fullyName
{
return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName]; } @end

1. OC调用js

流程我们创建UIWebView 在 代理中获取当前页面的js环境;就是JSContext

jsCXT = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

  然后在网页js中定义的方法,在这里我们就可以直接调用了;

//OC 调用JS

[jsCXT[@"sdkhi2"] callWithArguments:nil];

[jsCXT[@"sdkhito"] callWithArguments:@[@"aa"]];

2. JS 调用 OC

这里有两个方式,我们可以通过block的方法在oc里为js 注入一下方法,让js调用

//注册一个方法由js调用

jsCXT[@"ocsayhi"] = ^(NSString *name) {

NSLog(@"say hi to %@",name);

};

另外一个方法,稍麻烦一点,我们需要先声明协议,然后实现协议方法;通过JSExport 来暴露给JS环境调用

如上面的代码中的Person类;

调用方式:

Person *pp = [[Person alloc]init];

pp.firstName = @"cc";

pp.lastName = @"j";

pp.site = @"baidu.com";

jsCXT[@"pl"] = pp;

//以下是在当前jscxt中执行代码,当然网页js中也可以直接写

[jsCXT evaluateScript:@"alert(pl.fullyName())"];

最后完整示例工程:

https://github.com/cocoajin/TDDDemo/tree/master/JSAndOC

参考:http://www.skyfox.org/ios-wkwebview-cookie-opration.html

iOS中JS 与OC的交互(JavaScriptCore.framework)的更多相关文章

  1. iOS中js与objective-c的交互(转)

    因为在iOS中没有WebKit.Framework这个库的,所以也就没有 windowScriptObject对象方法了.要是有这个的方法的话 就方便多了,(ps:MacOS中有貌似) 现在我们利用其 ...

  2. iOS开发:JavaScriptCore.framework的简单使用--JS与OC的交互篇

    iOS7之后苹果为众猿推出了JavaScriptCore.framework这个框架,这个框架为大家在与JS交互上提供了很大帮助,可以在html界面上调用OC方法并传参,也可以在OC上调用JS方法并传 ...

  3. iOS下JS与OC互相调用(四)--JavaScriptCore

    前面讲完拦截URL的方式实现JS与OC互相调用,终于到JavaScriptCore了.它是从iOS7开始加入的,用 Objective-C 把 WebKit 的 JavaScript 引擎封装了一下, ...

  4. iOS下JS与OC互相调用(一)--UIWebView 拦截URL

    最近准备把之前用UIWebView实现的JS与原生相互调用功能,用WKWebView来替换.顺便搜索整理了一下JS 与OC 交互的方式,非常之多啊.目前我已知的JS 与 OC 交互的处理方式: * 1 ...

  5. iOS下JS与OC互相调用(六)--WKWebView + WebViewJavascriptBridge

    上一篇文章介绍了UIWebView 如何通过WebViewJavascriptBridge 来实现JS 与OC 的互相调用,这一篇来介绍一下WKWebView 又是如何通过WebViewJavascr ...

  6. iOS下JS与OC互相调用(五)--UIWebView + WebViewJavascriptBridge

    WebViewJavascriptBridge是一个有点年代的JS与OC交互的库,使用该库的著名应用还挺多的,目前这个库有7000+star.我去翻看了它的第一版本已经是4年前了,在版本V4.1.4以 ...

  7. iOS下JS与OC互相调用(八)--Cordova详解+实战

    扯两句,可以跳过 由于项目中Cordova相关功能一直是同事在负责,所以也没有仔细的去探究Cordova到底是怎么使用的,又是如何实现JS 与 OC 的交互.所以我基本上是从零开始研究和学习Cordo ...

  8. UIWebView中JS与OC交互 WebViewJavascriptBridge的使用

    一.综述 现在很多的应用都会在多种平台上发布,所以很多程序猿们都开始使用Hybrid App的设计模式.就是在app上嵌入网页,只要写一份网页代码,就可以跑在不同的系统上.在iOS中,app多是通过W ...

  9. iOS UIWebView 中 js调用OC 打开相册 获取图片, OC调用js 将图片加载到html上

    线上html <!DOCTYPE html> <html> <head> <title>HTML中用JS调用OC方法</title> < ...

随机推荐

  1. Java学习-001-JDK安装配置

    本节主要讲述在 Win7 64bit 系统下安装.配置 JDK8u25,敬请参阅.详细步骤如下: 一.JDK下载 您可到 官方网站 或 我的云盘 下载,对应的JDK8u25的安装程序,下载过程不再赘述 ...

  2. ArrayBlockingQueue,BlockingQueue分析

    BlockingQueue接口定义了一种阻塞的FIFO queue,每一个BlockingQueue都有一个容量,让容量满时往BlockingQueue中添加数据时会造成阻塞,当容量为空时取元素操作会 ...

  3. CentOS编译安装PHP 7.0

    问题1: Cannot find ldap.h 解决办法: yum install openldapyum install openldap-devel 问题2: Cannot find ldap l ...

  4. CAS无锁算法与ConcurrentLinkedQueue

    CAS:Compare and Swap 比较并交换 java.util.concurrent包完全建立在CAS之上的,没有CAS就没有并发包.并发包借助了CAS无锁算法实现了区别于synchroni ...

  5. Scrum 项目7.0

    一.内容 1.回顾组织 主题:“我们怎样才能在下个sprint中做的更好?” 时间:设定为1至2个小时. 参与者:整个团队. 场所:能够在不受干扰的情况下讨论. 秘书:指定某人当秘书,筹备.记录.整理 ...

  6. Sring控制反转(Inversion of Control,Ioc)也被称为依赖注入(Dependency Injection,DI)原理用反射和代理实现

    首先我有一个数据访问层接口: public interface StudentDao { void save(Student stu); } 和实现类: 1.mysql实现类 public class ...

  7. ligerui_ligerTree_007_ligerTree动态加载节点

    ligerui:ligerTree:动态加载节点: 源码地址:http://download.csdn.net/detail/poiuy1991719/8571255 效果图: 代码:json.txt ...

  8. ASP标准控件的重要性

    1.BackColor 属性:用于显示ListBox控件中的文本和图形的背景颜色,默认为白色(Window) 2.BorderStyle 属性:控制在列表框ListBox周围绘制的边框的类型,其枚举值 ...

  9. [xampp]在Crunch Bang下安装xampp1.8.3

    1.下载linux下 的xampp安装包 xampp-linux-1.8.3-5-installer.run 2.终端下, 给执行权限 sudo chmod +x ./xampp-linux-1.8. ...

  10. AppleWatch___学习笔记(一)开发思路和框架

    一.开发须知 如果你没有开发过 iphone,直接来做watch,我建议你不要这么做,不是不可以,而是目前所有的第三方应用都必须基于iphone的扩展,原生的watch应用,苹果目前还没有开放给开发者 ...