iOS老司机的跨端跨平台Hybrid开发Tips
本文正在参加「金石计划 . 瓜分6万现金大奖」
前言
- Native与H5的混合开发是目前大前端绕不开的技术点, 在实际业务场景中有各种各样的应用
- 很多一线开发同学都会使用
Hybrid混合开发
中的各种技术及API, 去完成各种相互调用的需求 - 知其然, 知其所以然. 作为一个有追求的大前端从业者, 我们一起来探究一下iOS中的
Hybrid混合开发
的前世今生. - 文章纯手打, 抛砖引玉, 如有错误还请评论区指正, 先行谢过了:)
1. 原生与前端交互
1.1 什么是JavaScriptCore?
JavaScriptCore
为原生编程语言Objective-C
、Swift
提供调用JavaScript
程序的动态能力,还能为 JavaScript
提供原生能力来弥补前端所缺能力。- 桥梁作用
JavaScriptCore
,原本是WebKit
中用来解释执行JavaScript
代码的核心引擎-
- 解释执行
JavaScript
代码的引擎自JavaScript
诞生起就有,不断演进,一直发展到现在
- 解释执行
-
- 如今苹果公司有
JavaScriptCore
引擎、谷歌有 V8 引擎
- 如今苹果公司有
-
- iOS7 之前,苹果公司没有开放
JavaScriptCore
引擎。
- iOS7 之前,苹果公司没有开放
-
- 从 iOS7 开始,苹果公司开始将
JavaScriptCore
框架引入 iOS 系统,并将其作为系统级的框架提供给开发者使用
- 从 iOS7 开始,苹果公司开始将
JavaScriptCore
框架的框架名是 JavaScriptCore.framework。
1.2 JavaScriptCore 框架的关键类分解剖析
- JavaScriptCore 框架主要由
JSVirtualMachine
、JSContext
、JSValue
类组成。 JSVirturalMachine
的作用,是为 JavaScript 代码的运行提供一个虚拟机环境。-
JSContext
是 JavaScript 运行环境的上下文,负责原生和 JavaScript 的数据传递。
-
-
JSValue
是JavaScript
的值对象,用来记录 JavaScript 的原始值,并提供进行原生值对象转换的接口方法。
-
1.3 JavaScript 代码的 JavaScriptCore 和原生应用是怎么交互的呢
-
JavaScriptCore
和原生应用要想交互,首先要有JSContext
。 -
除了
Block
外,我们还可以通过JSExport
协议来实现在JavaScript
中调用原生代码, -
- 也就是原生代码中让遵循
JSExport
协议的类,能够供JavaScript
使用。
- 也就是原生代码中让遵循
``` - (void)testJavaScriptCore { // 创建JSVirtualMachine对象 JSVirtualMachine jsvm = [JSVirtualMachine new]; // 使用 jsvm的JSContext对象 JSContext ct = [[JSContext alloc] initWithVirtualMachine:jsvm];
//通过JavaScriptCore在原生代码中调用JavaScript变量 // 解析执行JavaScript脚本 [ct evaluateScript:@"var i = 1 + 2"];
// 转换"i"变量为原生对象 NSNumber *iNumber = [ct[@"i"] toNumber]; NSLog(@"var i is %@, iNumber is %@", ct[@"i"], iNumber);
// 解析执行 JavaScript脚本 [ct evaluateScript:@"function subtraction(x, y) { return x - y }"];
// 获得 subtraction 函数 JSValue *subtraction = ct[@"subtraction"];
// 传入参数执行subtraction函数 JSValue *resultValue = [subtraction callWithArguments:@[@(3), @(1)]];
// 将 subtraction 函数执行的结果转成原生NSNumber来使用 NSLog(@"function is %@, reusltValue is %@", subtraction, [resultValue toNumber]); } ```
1.4 iOS中Native和JavaScriptCore交互小结
- 总的来说,
JavaScriptCore
提供了前端与原生相互调用的接口,接口层上主要用的是JSContext
和JSValue
这两个类, - 通过
JSValue
的evaluateScript
方法、Block
赋值context
、JSExport
协议导出来达到互通的效果。
2. Hybrid混合开发框架的几个里程牌
2.1 基于JavaScript和WebView的跨平台方案Cordova
Cordova
的前身是PoneGap
, 后被Apache收购, 成立Cordova
项目组Cordova
的方案主要是通过H5来构建页面, 再将其显示在各个平台的WebView中.Cordova
官方图:
2.1.1 Cordova的优缺点
Cordova
的优点显而易见, 背靠Apache这样的大厂, 底层代码稳定, 文档清晰, 应用广泛.- 但是它默认是不能调用Native的一些服务的(如相机、蓝牙等硬件), 所以需要通过JavaScript进行桥接调用Native的一些API来完成某些基于硬件的功能.
- 本身的用户体验、性能相对Native控件并不是太流畅, Native更新迭代的过程中容易产生很多适配问题.
2.2 久经考验的React Native
React Native
是Facebook在2015年4月开源出来的跨平台开发框架, 是Facebook基于早先开源的JS框架React在原生移动应用平台的衍生应用.React Native
使用JS语言, 类似于H5的JSX
, 以及CSS来开发移动App, 降低了使用React框架的H5前端同学的学习成本.- 在保留基本渲染能力的基础上, 用原生自带的UI组件实现核心渲染引擎, 从而保证了良好的渲染效果.
- 但是, 由于React Native的本质是通过JavaScript VM调用原生接口, 相对Native组件通信较低效, 而且RN框架本身不负责渲染, 是间接通过原生进行渲染的.(参考大厂Airbnb由RN转向Native.)
2.3 Google主推的跨平台解决方案Flutter
- Flutter使用Skia渲染引擎, 直接通过CPU、GPU进行图形绘制, 不需要依赖任何Native控件.
- Android操作系统中, 我们编写的Native控件实际上也是依赖于Skia进行绘制渲染, 所以Flutter在某些Android小K做系统上, 甚至还要高于安卓原生(因为安卓原生中的Skia必须随着操作系统进行更新, 二Flutter SDK中总是保持最新的Skia引擎).
- 而类似于React Native框架, 必须通过桥接操作先转成Native控件进行调用, 之后再进行渲染.
3. 一些小结
- 大前端中主流的3种跨平台框架各有利弊, 选取哪个方案, 还是要由实际业务场景及项目具体情况决定.
- 就像我们讨论
OOP POP FunctionalProgramming
究竟是哪个好? - 最后还是MOP(Market Oriented Programming), 市场和具体业务情况决定了我们的技术选型, 应避免一味的炫技. 毕竟, 技术的成长和业务的发展是相辅相成的双生:)
发文不易, 喜欢点赞的人更有好运气👍 :), 定期更新+关注不迷路~
ps:欢迎加入笔者18年建立的研究iOS审核及前沿技术的三千人扣群:662339934,坑位有限,备注“掘金网友”可被群管通过~
本文正在参加「金石计划 . 瓜分6万现金大奖」
- iOS老司机聊聊实际项目开发中的<<人月神话>>
- iOS老司机可落地在中大型iOS项目中的5大接地气设计模式合集
- iOS老司机的跨端跨平台Hybrid开发Tips
- iOS老司机的2022年回顾, 聊聊寒冬下的实用<<谈判力>>
- iOS老司机可落地的中大型iOS项目中的设计模式优化Tips_桥接模式
- iOS老司机的多线程PThread学习分享
- iOS老司机整理, iOSer必会的经典算法_2
- iOS老司机的<<蓝海转型>>读书分享
- iOS老司机的<<程序员的自我修养:链接、装载与库>>读书分享
- iOS老司机的接地气算法Tips
- iOS老司机的RunLoop原理探究及实用Tips
- iOS老司机整理, iOSer必会的经典算法_1
- iOS老司机的App启动优化Tips, 让启动速度提升10%
- iOS老司机的网络相关Tips
- 恋上数据结构与算法
- iOS老司机带你一起把App的崩溃率降到0.1%以下
- 探究Swift的String底层实现
- iOS老司机万字整理, 可能是最全的Swift Tips
- iOS老司机可落地的中大型iOS项目中的设计模式优化Tips
- 聊一聊Swift中的闭包