最近项目里面有有个商品活动界面,要与web端传值,将用户在网页点击的商品id 传给客户端,也就是js交互,其实再说明白一点就是方法的互相调用而已。

本文叙述下如何进行原生的JavaScript交互

本文包括JS调用OC方法并传值,OC调用JS方法并传值

本来想把html放进服务器里面,然后访问,但是觉得如果html在本地加载更有助于理解,特把html放进项目里

HTML代码

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div style="margin-top: 20px">
<h2>JS与OC交互</h2>
<input type="button" value="唤起本地方法(call)" onclick="tianbai.call()">
</div>
<div>
<input type="button" value="唤起getCall:(NSString *)callString传值" onclick="call()">
</div> <script> var call = function()
{
var callInfo = JSON.stringify({"jianshu": "http://www.jianshu.com/users/55c8fdc3c6e7/latest_articles"});
tianbai.getCall(callInfo);
} var Callback = function(str)
{
alert(str);
}
var alerCallback = function()
{
alert('成功');
}
</script>
</body>
</html>

上面html的代码:建立了两个button

第一个button绑定了 tianbai.call() 方法,这里 tianbai 是一个对象,这个对象的作用下面OC代码中会说明, tianbai.call() 代表 tianbai 对象调用call() 方法

第二个button绑定了 call() 的方法,调用的是下面JavaScript中的 call() 方法,在 JavaScript 的 call() 里面,定义一个 callInfo 参数,方法中tianbai.getCall(callInfo) 代表 tianbai 对象调用 getCall 方法并传参数 callInfo ,下面两个方法是OC调用JavaScript方法,其中Callback传回str,alerCallback为OC仅调用JavaScript方法!

OC代码

demo采用原生的JavaScriptCore类

引入三个名词:

  1. JSContext:给JavaScript提供运行的上下文环境
  2. JSValue:JavaScript和Objective-C数据和方法的桥梁
  3. JSExport:这是一个协议,如果采用协议的方法交互,自己定义的协议必须遵守此协议

ViewController.h中的代码(代码过长,方法说明都在注释里)

#import <UIKit/UIKit.h>
//导入头文件
#import <JavaScriptCore/JavaScriptCore.h> @protocol JSObjcDelegate <JSExport>
//tianbai对象调用的JavaScript方法,必须声明!!!
- (void)call;
- (void)getCall:(NSString *)callString; @end
@interface ViewController : UIViewController<UIWebViewDelegate,JSObjcDelegate>
@property (nonatomic, strong) JSContext *jsContext;
@property (strong, nonatomic) UIWebView *webView; @end

ViewController.m中的代码(代码过长,方法说明都在注释里)

JavaScriptCore中web页面调用原生应用的方法可以用Delegate或Block两种方法,此文以按Delegate讲解。

设置webView

self.webView = [[UIWebView alloc]initWithFrame:CGRectMake(0, 20, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
self.webView.delegate = self;
//从本地加载html文件
NSString* path = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
NSURL* url = [NSURL fileURLWithPath:path];
NSURLRequest* request = [NSURLRequest requestWithURL:url] ;
[self.webView loadRequest:request]; [self.view addSubview:self.webView];

JavaScript的tianbai是一个对象,充当原生应用和web页面之间的一个桥梁。用来调用方法

webview加载完成调用代理

- (void)webViewDidFinishLoad:(UIWebView *)webView {

      // 设置javaScriptContext上下文
self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
//将tianbai对象指向自身
self.jsContext[@"tianbai"] = self;
self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
context.exception = exceptionValue;
NSLog(@"异常信息:%@", exceptionValue);
};
}

将对象指向自身后,如果调用 tianbai.call() 会响应下面的方法,OC方法中调用js中的Callback方法,并传值

- (void)call{
NSLog(@"call");
// 之后在回调JavaScript的方法Callback把内容传出去
JSValue *Callback = self.jsContext[@"Callback"];
//传值给web端
[Callback callWithArguments:@[@"唤起本地OC回调完成"]];
}

将对象指向自身后,如果调用 tianbai.getCall(callInfo) 会响应下面的方法,OC方法中仅调用JavaScript中的alerCallback方法

- (void)getCall:(NSString *)callString{
NSLog(@"Get:%@", callString);
// 成功回调JavaScript的方法Callback
JSValue *Callback = self.jsContext[@"alerCallback"];
[Callback callWithArguments:nil];
}

将对象指向自身后,还可以向html注入js

- (void)alert{

    // 直接添加提示框
NSString *str = @"alert('OC添加JS提示成功')";
[self.jsContext evaluateScript:str]; }

JS调用OC方法并传值,OC调用JS方法并传值////////////////////////zz的更多相关文章

  1. 如何写 JS 的链式调用 ---》JS 设计模式《----方法的链式调用

    1.以$ 函数为例.通常返回一个HTML元素或一个元素集合. 代码如下: function $(){ var elements = []; ;i<arguments.length;i++){ v ...

  2. js中子页面父页面方法和变量相互调用

    (1)子页面调用父页面的方法或者变量: window.parent.方法()或者变量名window.parent相当于定位到父页面 之后的操作和在父页面中写代码一样写 window.parent.aa ...

  3. easyUi弹出window窗口传值与调用父页面的方法,子页面给父页面赋值

    <!-- 父页面 --> <!DOCTYPE html PUBLIC "-/W3C/DTD HTML 4.01 Transitional/EN" "ht ...

  4. (转)Silverlight调用的JS方法返回对象数组的处理方法

    最近在做Silverlight应用,需要用Silverlight调用页面中Javascript方法.这 个JS方法返回一个对象数组给Silverlight.对于这个对象数组怎么在Silverlight ...

  5. 「Vue」父子组件之间的传值及调用方法

    a.父组件向子组件传值data(){},props数据区别data中的数据可读可写,是自己的数据props是个数组,中的数据是父组件传递过来的,只读不能写<login :dmsg='msg'&g ...

  6. jsp页面:js方法里嵌套java代码(是操作数据库的),如果这个js 方法没被调用,当jsp页面被解析的时候,不管这个js方法有没有被调用这段java代码都会被执行?

    jsp页面:js方法里嵌套java代码(是操作数据库的),如果这个js 方法没被调用,当jsp页面被解析的时候,不管这个js方法有没有被调用这段java代码都会被执行? 因为在解析时最新解析的就是JA ...

  7. JS高级. 06 缓存、分析解决递归斐波那契数列、jQuery缓存、沙箱、函数的四种调用方式、call和apply修改函数调用方法

    缓存 cache 作用就是将一些常用的数据存储起来 提升性能 cdn //-----------------分析解决递归斐波那契数列<script> //定义一个缓存数组,存储已经计算出来 ...

  8. vue.js组件之间通讯--父组件调用子组件的一些方法,子组件暴露一些方法,让父组件调用

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  9. Vue父子组件相互传值及调用方法的方案

    Vue父子组件相互传值及调用方法的方案 一.调用方法: 1.父组件调用子组件方法: 2.子组件调用父组件方法: 参考:https://www.cnblogs.com/jin-zhe/p/9523782 ...

  10. JS设计模式——6.方法的链式调用

    什么是链式调用 这个很容易理解,例如: $(this).setStyle('color', 'red').show(); 分解链式调用 链式调用其实是两个部分: 1.操作对象(也就是被操作的DOM元素 ...

随机推荐

  1. Android测试之 APK重签名方法

    方法一:命令行重签名 D:\>keytool -helpkeytool 用法: -certreq [-v] [-protected] [-alias <别名>] [-sigalg & ...

  2. 弹性盒子布局flexbox

    弹性盒子display:flexbox一般应用于父元素的容器上,然后对子元素来进行弹性布局 设置了flexbox的父元素不能设置具体的宽度与高度的值,而是通过子元素来设置值,父元素弹性的包裹既可 相关 ...

  3. Softmax回归

    Reference: http://ufldl.stanford.edu/wiki/index.php/Softmax_regression http://deeplearning.net/tutor ...

  4. 通用数据库操作类,前端easyui-datagrid,form

    实现功能:     左端datagrid显示简略信息,右侧显示选中行详细信息,数据库增删改 (1)点击选中行,右侧显示详细信息,其中[新增].[修改].[删除]按钮可用,[保存]按钮禁用 (2)点击[ ...

  5. 细读cow.osg

    细读cow.osg 转自:http://www.cnblogs.com/mumuliang/archive/2010/06/03/1873543.html 对,就是那只著名的奶牛. //Group节点 ...

  6. 利用jquery发送form表单

    $("#rap_save_draft").click(function(){ rap_start_editor.sync();//同步KindEditor的内容 // 取得要提交的 ...

  7. SQL Server中的事物

    1.事务的四个属性 原子性Atomicity,一致性Consistency,隔离性Isolation,持久性Durability ,即ACID特性. 原子性:事务必须是一个完整工作的单元,要么全部执行 ...

  8. MySQL性能分析及explain的使用

    MySQL性能分析及explain用法的知识 1.使用explain语句去查看分析结果 如explain select * from test1 where id=1;会出现:id  selectty ...

  9. Android课程---关于数据存储的学习(2)

    手机外部存储的学习 activity_data2.xml <?xml version="1.0" encoding="utf-8"?> <Li ...

  10. 如何使用QQ号进行快捷登录

    注意:第三步回调地址域名必须严格按照规范填写否则无法使用.QQ回调地址域名为您的网站地址无论您是否为DISCUZ论坛,请全部使用网站申请.discuz论坛申请的KEY无效注册QQ登录应用将会获得该应用 ...