- 浏览: 26769 次
- 性别:
- 来自: 上海
-
文章分类
最新评论
转载于: iOS开发技术分享
前言
ObjectiveC与Js交互是常见的需求,可对于新手或者所谓的高手而言,其实并不是那么简单明了。这里只介绍iOS7.0后出来的JavaScriptCore framework。
关于JavaScriptCore
本教程中所涉及到的几种类型:
JSContext, JSContext是代表JS的执行环境,通过-evaluateScript:方法就可以执行一JS代码
JSValue, JSValue封装了JS与ObjC中的对应的类型,以及调用JS的API等
JSExport, JSExport是一个协议,遵守此协议,就可以定义我们自己的协议,在协议中声明的API都会在JS中暴露出来,才能调用
ObjC与JS交互方式
通过JSContext,我们有两种调用JS代码的方法:
1、直接调用JS代码
2、在ObjC中通过JSContext注入模型,然后调用模型的方法
直接调用JS代码
这种方式是没有注入模型到JS中的。这种方式使用起来不太合适,通常在JS中有很多全局的函数,为了防止名字重名,使用模型的方式是最好不过了。通过我们协商好的模型名称,在JS中直接通过模型来调用我们在ObjC中所定义的模型所公开的API。
通过注入模型的方式交互
首先,我们需要先定义一个协议,而且这个协议必须要遵守JSExport协议。
接下来,我们还需要定义一个模型:
实现这个模型:
接下来,我们在controller中在webview加载完成的代理中,给JS注入模型。
我们是通过webView的valueForKeyPath获取的,其路径为documentView.webView.mainFrame.javaScriptContext。
这样就可以获取到JS的context,然后为这个context注入我们的模型对象。
我们先写两个JS方法:
这里我们定义了两个JS方法,一个是jsFunc,不带参数。
另一个是jsParamFunc,带一个参数。
接下来,我们在html中的body中添加以下代码:
现在就可以测试代码了。
当我们点击第一个按钮:Call ObjC system camera时,
通过OCModel.callSystemCamera(),就可以在HTML中通过JS调用OC的方法。
在OC代码中,我们的callSystemCamera方法体中,添加了以下两行代码,就是获取HTML中所定义的JS就去jsFunc,然后调用它。
这样就可以在JS调用OC方法时,也让OC反馈给JS。
看看下面传字典参数:
获取我们在HTML中定义的jsParamFunc方法,然后调用它并传了一个字典作为参数。
好了,就讲这么多吧,如果想要Demo源代码,请到
github:https://github.com/CoderJackyHuang/IOSCallJsOrJsCallIOS
想学习Swift版的?请阅读:
http://mp.weixin.qq.com/s?__biz=MzIzMzA4NjA5Mw==&mid=214070747&idx=1&sn=57b45fa293d0500365d9a0a4ff74a4e1#rd
前言
ObjectiveC与Js交互是常见的需求,可对于新手或者所谓的高手而言,其实并不是那么简单明了。这里只介绍iOS7.0后出来的JavaScriptCore framework。
关于JavaScriptCore
本教程中所涉及到的几种类型:
JSContext, JSContext是代表JS的执行环境,通过-evaluateScript:方法就可以执行一JS代码
JSValue, JSValue封装了JS与ObjC中的对应的类型,以及调用JS的API等
JSExport, JSExport是一个协议,遵守此协议,就可以定义我们自己的协议,在协议中声明的API都会在JS中暴露出来,才能调用
ObjC与JS交互方式
通过JSContext,我们有两种调用JS代码的方法:
1、直接调用JS代码
2、在ObjC中通过JSContext注入模型,然后调用模型的方法
直接调用JS代码
// 一个JSContext对象,就类似于Js中的window, // 只需要创建一次即可。 self.jsContext = [[JSContext alloc] init]; // jscontext可以直接执行JS代码。 [self.jsContext evaluateScript:@"var num = 10"]; [self.jsContext evaluateScript:@"var squareFunc = function(value) { return value * 2 }"]; // 计算正方形的面积 JSValue *square = [self.jsContext evaluateScript:@"squareFunc(num)"]; // 也可以通过下标的方式获取到方法 JSValue *squareFunc = self.jsContext[@"squareFunc"]; JSValue *value = [squareFunc callWithArguments:@[@"20"]]; NSLog(@"%@", square.toNumber); NSLog(@"%@", value.toNumber);
这种方式是没有注入模型到JS中的。这种方式使用起来不太合适,通常在JS中有很多全局的函数,为了防止名字重名,使用模型的方式是最好不过了。通过我们协商好的模型名称,在JS中直接通过模型来调用我们在ObjC中所定义的模型所公开的API。
通过注入模型的方式交互
首先,我们需要先定义一个协议,而且这个协议必须要遵守JSExport协议。
@protocol JavaScriptObjectiveCDelegate <JSExport> // JS调用此方法来调用OC的系统相册方法 - (void)callSystemCamera; // 在JS中调用时,函数名应该为showAlertMsg(arg1, arg2) // 这里是只两个参数的。 - (void)showAlert:(NSString *)title msg:(NSString *)msg; // 通过JSON传过来 - (void)callWithDict:(NSDictionary *)params; // JS调用Oc,然后在OC中通过调用JS方法来传值给JS。 - (void)jsCallObjcAndObjcCallJsWithDict:(NSDictionary *)params; @end
接下来,我们还需要定义一个模型:
// 此模型用于注入JS的模型,这样就可以通过模型来调用方法。 @interface HYBJsObjCModel : NSObject <JavaScriptObjectiveCDelegate> @property (nonatomic, weak) JSContext *jsContext; @property (nonatomic, weak) UIWebView *webView; @end
实现这个模型:
@implementation HYBJsObjCModel - (void)callWithDict:(NSDictionary *)params { NSLog(@"Js调用了OC的方法,参数为:%@", params); } // Js调用了callSystemCamera - (void)callSystemCamera { NSLog(@"JS调用了OC的方法,调起系统相册"); // JS调用后OC后,又通过OC调用JS,但是这个是没有传参数的 JSValue *jsFunc = self.jsContext[@"jsFunc"]; [jsFunc callWithArguments:nil]; } - (void)jsCallObjcAndObjcCallJsWithDict:(NSDictionary *)params { NSLog(@"jsCallObjcAndObjcCallJsWithDict was called, params is %@", params); // 调用JS的方法 JSValue *jsParamFunc = self.jsContext[@"jsParamFunc"]; [jsParamFunc callWithArguments:@[@{@"age": @10, @"name": @"lili", @"height": @158}]]; } - (void)showAlert:(NSString *)title msg:(NSString *)msg { dispatch_async(dispatch_get_main_queue(), ^{ UIAlertView *a = [[UIAlertView alloc] initWithTitle:title message:msg delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil]; [a show]; }); } @end
接下来,我们在controller中在webview加载完成的代理中,给JS注入模型。
#pragma mark - UIWebViewDelegate - (void)webViewDidFinishLoad:(UIWebView *)webView { self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; // 通过模型调用方法,这种方式更好些。 HYBJsObjCModel *model = [[HYBJsObjCModel alloc] init]; self.jsContext[@"OCModel"] = model; model.jsContext = self.jsContext; model.webView = self.webView; self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) { context.exception = exceptionValue; NSLog(@"异常信息:%@", exceptionValue); }; }
我们是通过webView的valueForKeyPath获取的,其路径为documentView.webView.mainFrame.javaScriptContext。
这样就可以获取到JS的context,然后为这个context注入我们的模型对象。
我们先写两个JS方法:
var jsFunc = function() { alert('Objective-C call js to show alert'); } var jsParamFunc = function(argument) { document.getElementById('jsParamFuncSpan').innerHTML = argument['name']; }
这里我们定义了两个JS方法,一个是jsFunc,不带参数。
另一个是jsParamFunc,带一个参数。
接下来,我们在html中的body中添加以下代码:
<div style="margin-top: 100px"> <h1>Test how to use objective-c call js</h1> <input type="button" value="Call ObjC system camera" onclick="OCModel.callSystemCamera()"> <input type="button" value="Call ObjC system alert" onclick="OCModel.showAlertMsg('js title', 'js message')"> </div> <div> <input type="button" value="Call ObjC func with JSON " onclick="OCModel.callWithDict({'name': 'testname', 'age': 10, 'height': 170})"> <input type="button" value="Call ObjC func with JSON and ObjC call js func to pass args." onclick="OCModel.jsCallObjcAndObjcCallJsWithDict({'name': 'testname', 'age': 10, 'height': 170})"> </div> <div> <span id="jsParamFuncSpan" style="color: red; font-size: 50px;"></span> </div>
现在就可以测试代码了。
当我们点击第一个按钮:Call ObjC system camera时,
通过OCModel.callSystemCamera(),就可以在HTML中通过JS调用OC的方法。
在OC代码中,我们的callSystemCamera方法体中,添加了以下两行代码,就是获取HTML中所定义的JS就去jsFunc,然后调用它。
JSValue *jsFunc = self.jsContext[@"jsFunc"]; [jsFunc callWithArguments:nil];
这样就可以在JS调用OC方法时,也让OC反馈给JS。
看看下面传字典参数:
- (void)jsCallObjcAndObjcCallJsWithDict:(NSDictionary *)params { NSLog(@"jsCallObjcAndObjcCallJsWithDict was called, params is %@", params); // 调用JS的方法 JSValue *jsParamFunc = self.jsContext[@"jsParamFunc"]; [jsParamFunc callWithArguments:@[@{@"age": @10, @"name": @"lili", @"height": @158}]]; }
获取我们在HTML中定义的jsParamFunc方法,然后调用它并传了一个字典作为参数。
好了,就讲这么多吧,如果想要Demo源代码,请到
github:https://github.com/CoderJackyHuang/IOSCallJsOrJsCallIOS
想学习Swift版的?请阅读:
http://mp.weixin.qq.com/s?__biz=MzIzMzA4NjA5Mw==&mid=214070747&idx=1&sn=57b45fa293d0500365d9a0a4ff74a4e1#rd
发表评论
-
Objective-C与JavaScript交互的那些事
2016-05-04 10:44 496转载于:http://www.cocoachina.com/i ... -
Import Cheetah3D Model in SceneKit
2015-01-23 16:18 779http://blog.manbolo.com/2014/08 ... -
SCNTechnique in SceneKit
2015-02-03 16:58 1412转摘与:http://okita.com/alex/ SCN ... -
Scene Kit (翻译)
2015-01-23 10:35 644前言 http://segmentfault.com/ ... -
iOS 图形编程总结
2015-01-22 11:07 678iOS实现图形编程可以 ... -
Introduction to Scene Kit
2015-01-21 14:35 506Scene Kit Programming Guide[/b] ... -
使用scenekit的时候不能打开程序
2015-01-21 13:59 640问题一: nib上能加载class 程序却找不到,在使用sce ... -
报错: dyld: Library not loaded
2015-01-21 13:02 1033一、问题 dyld: Library not loaded: ... -
iOS Sprite Kit最新特性Physics Field虚拟物理场Swift测试
2015-01-19 16:30 584转载于:http://blog.csdn.ne ... -
Sprite Kit编程指南(1)-深入Sprite Kit
2015-01-19 15:53 653Sprite Kit编程指南(1)- ...
相关推荐
3. 数据同步:通过JavaScript与Swift的交互,实现原生应用与网页的数据同步。 总结,WKWebView的封装是iOS开发中的一个重要环节,通过封装可以提高代码复用性,简化网页加载流程,并且便于管理和控制。理解并掌握...
项目资源包含:可运行源码+数据集+文档 python + numpy, pandas, matplotlib, pyecharts, wordcloud 适用人群:学习不同技术领域的小白或进阶学习者;可作为课程设计、大作业、工程实训或初期项目立项。 数据来源:数据集taxis.csv从网络下载 数据清洗:异常值与缺失值的处理:有一些数据distance(乘车距离)为零而且上下车地点为空,还有些一些数据的payment(支付方式)为空。 数据预处理:将列名更改成中文 标准化与归一化: 数据分析: 数据可视化:
TypeScript 入门教程
人脸识别项目实战
本资源汇总了 历届全国电子设计竞赛(电赛)真题+模拟题,涵盖 电路设计、嵌入式系统、信号处理、自动控制等核心考点,并提供详细解析及综合测评,帮助参赛者高效备赛、查漏补缺、提升实战能力。 适用人群: 适合 准备参加电子设计竞赛的大学生、电赛爱好者、电子信息类相关专业的学生,以及希望提高电子设计和电路分析能力的工程师。 能学到什么: 电赛考察重点:熟悉往届竞赛的命题方向及考核重点。 电路设计与仿真:提升模拟电路、数字电路、单片机等核心技能。 问题分析与解决能力:通过综合测评找到薄弱点并针对性提升。 实战经验:掌握竞赛策略,提高应试效率和设计能力。 阅读建议: 建议先 通读真题,了解题型与解题思路,然后 结合模拟题实战演练,查找不足并通过测评强化练习,逐步提升竞赛能力。
2024人工智能如何塑造未来产业:AI对各行业组织带来的的变革研究研究报告.pdf
人脸识别项目源码实战
给大家分享一套课程——Vulkan原理与实战课程
c语言学习
海豚鲸鱼数据集 5435张图 正确识别率可达92.6% 可识别:海豚 虎鲸 蜥蜴 海豹 鲨鱼 龟 支持yolov8格式标注
答谢中书书教学设计.docx
人脸识别项目源码实战
c语言学习
人脸识别项目源码实战
人脸识别项目实战
本美发门店管理系统有管理员和用户两个角色。用户功能有项目预定管理,产品购买管理,会员充值管理,余额查询管理。管理员功能有个人中心,用户管理,美容项目管理,项目类型管理,项目预定管理,产品库存管理,产品购买管理,产品入库管理,会员卡管理,会员充值管理,余额查询管理,产品类型管理,系统管理等。因而具有一定的实用性。 本站是一个B/S模式系统,采用SSM框架,MYSQL数据库设计开发,充分保证系统的稳定性。系统具有界面清晰、操作简单,功能齐全的特点,使得美发门店管理系统管理工作系统化、规范化。本系统的使用使管理人员从繁重的工作中解脱出来,实现无纸化办公,能够有效的提高美发门店管理系统管理效率。 关键词:美发门店管理系统;SSM框架;MYSQL数据库;Spring Boot 1系统概述 1 1.1 研究背景 1 1.2研究目的 1 1.3系统设计思想 1 2相关技术 2 2.1 MYSQL数据库 2 2.2 B/S结构 3 2.3 Spring Boot框架简介 4 3系统分析 4 3.1可行性分析 4 3.1.1技术可行性 4 3.1.2经济可行性 5 3.1.3操作可行性 5 3.2系
内容概要:本文档介绍了基于SSA-CNN-GRU麻雀算法优化卷积门控循环单元数据分类预测的详细项目实例,重点讲述了该项目的背景、目标、挑战与解决方案、技术特点、应用领域等方面的内容。文档详细记录了从项目启动、数据预处理、算法设计(SSA优化CNN-GRU模型)、构建与评估模型到实现美观的GUI界面整个过程,并讨论了防止过拟合的技术如正则化、早停和超参数优化。另外还涵盖了项目扩展的可能性、部署和应用策略、需要注意的地方以及未来改进的方向。全文强调了模型的泛化能力和计算效率,展示了该混合算法模型在实际应用中的优越性能。 适合人群:具备一定的Python编程经验及机器学习基础知识的研究人员和技术人员;对深度学习、智能优化算法及实际应用感兴趣的学者和从业者;寻求提升数据分析和预测准确性的金融分析师、数据科学家等相关专业人士。 使用场景及目标:本文档非常适合用作学习和参考资料,以掌握如何将SSA、CNN与GRU三种先进技术结合起来进行复杂的分类和预测问题求解。具体应用场景包括但不限于以下几个方面:金融领域——股票价格预测;医疗保健领域——辅助诊断;工业制造——预防性维护;智能家居——个性化服务;以及其他涉及到时序数据分析和多模态数据处理的场合。文档既包含了理论知识又提供了完整的源代码示例,可以帮助读者理解算法原理并通过实践中加深对其的认识。 其他说明:该项目不仅仅是关于算法的设计实现,更是有关于系统的整体架构规划以及工程上的考量,比如环境准备(确保环境洁净、必要包的安装等)、数据准备、GPU配置支持等等。同时文中给出了详细的代码片段,方便开发者理解和复现实验成果。值得注意的是,虽然文中提供了一套通用解决方案,但在真实场景下还需要针对性的调整参数或修改网络结构来达到最好的性能效果。此外,对于追求更高的预测精度或解决更大规模的问题,作者建议进一步探索深度强化学习等高级技术和多任务学习策略,并且考虑使用增量学习让模型能够适应新数据而不必重新训练整个模型。最后提到安全性和隐私保护也是项目实施过程中的重要因素,要妥善保管用户的敏感信息并且做到合法合规地收集和使用数据。
人脸识别项目实战
人脸识别项目实战
水下垃圾检测数据集,基于voc和yolo标注的两种格式,共23,056个文件,已经划分了训练集和验证集、测试集。并且提供了真实水下的视频数据,可以用作视频推理