iOS动态化之React Native

近段时间来,关于移动客户端方面的动态化解决方案有了不少。之前的JSPatch,滴滴的解决方法:DynamicCocoa,微信iOS开发团队的解决方案:OCS。而今天需要说道的是React Native。

1. 背景

首先简单介绍下滴滴和微信的解决方案。

  • 1.1 DynamicCocoa
    DynamicCocoa 可以让现有的 Objective-C 代码转换生成中间*代码(JS),下发后动态执行,相比其他动态化方案,优势在于:

    • 使用原生技术栈:使用者完全不用接触到 JS 或任何中间代码,保持原生的 Objective-C 开发、调试方式不变
    • 无需重写已有代码:已有 native 模块能很方便的变成动态化插件
    • 语法支持完备性高:支持绝大多数日常开发中用到的语法,不用担心这不支持那不支持
    • 支持 HotPatch改完 bug 后直接从源码打出 patch,一站式解决动态化和热修复需

    最重要DynamicCocoa有一下特点:

    • 完整的 Class 定义:interface、category、class extension、method、property,最重要的是支持完备的 ivar 定义,保持和 native 完全一致的实例内存结构
    • ARC:可以正确处理 strong、weak、unsafe_unretained 等对象的引用计数,对象的 ivar 也可以正确的释放
    • C 函数:支持 C 函数的定义与 C 函数的调用、内联函数的调用
    • 可变参数:支持 C 与 OC 的可变参数方法的调用,如 NSLog
    • struct:支持任意结构体的使用,无需额外处理
    • block:支持创建和调用任意参数类型的 block
    • 其他 OC 特性:如 @selector、@protocol、@encode、for..in 等
    • 其他 C 特性:支持使用宏、static 变量、全局变量,取地址等

    ps:DynamicCocoa完整介绍

  • 1.2 OCS
    OCS是全新设计的iOS动态化方案。我们定义了一套精确描述OC语义的字节码指令集(OCScript),开发了一套全自动编译器(OCSCompiler),实现了一个高性能的虚拟机(OCSVM)以及一个可以跟底层无缝对接的桥接器(OCSBridge)。我们首先使用OCS编译器把OC源码转化成OCS字节码,然后通过OCS桥接器实现OCS虚拟机与Native运行时的互联,最后使用OCS虚拟机对OCS字节码进行解释运算,并驱动Native运行时完成逻辑的执行,以此达到Native代码动态化的效果。OCS被用于iOS APP安装包减包、功能插件化、HotPatch等方方面面动态化需求。

    • OCS有哪些与众不同之处
      • 语义与OC保持严格一致
        OCS字节码指令集语义与OC/的语义保持严格一一对应关系,支持的数据类型也完全等同,运行过程无需进行任何转换,因此效率非常高。
      • 自动化工具支持
        OCS拥有完善的自动化工具链,OCS编译器支持绝大多数OC/C语法的转化,包括C方法、任意自定义结构体、任意自定义block。对于少数不支持的的语法,可以准确报错,引导用户进行规避,避免产生未定义行为。OCS编译器还可以准确识别OC/C代码的内存管理语义,可以正确生成内存管理相关的代码。特别对于ARC来说,可以准确生成Retain、Release代码,正确插入到生成代码中去。
      • 原生OC内存管理机制
        OCS虚拟机完全支持Native的内存管理机制,可以在正确的时机执行正确的内存释放逻辑,绝无延迟操作,彻底杜绝了Crash和爆内存风险的引入。
      • 抢占式多线程
        OCS虚拟机支持Native的抢占式多线程线程管理支持,完全支持Pthread、 GCD、 NSOperationqueue、 NSThread等各种线程模型,完全避免了额外引入Crash、卡顿与死锁风险。
      • 高性能汇编ABI
        OCS桥接器根据过程调用约定实现自定义OCSABI,使得虚拟机与Native底层实现直接通信,保证Native代码动态化引入额外性能损耗最小化,使得OCS动态化不仅普遍适用于普通逻辑转化,对于对性能要求苛刻的有复杂排版的滑动列表,OCS也有极佳的表现,动态化后掉帧率增长量几乎可以忽略不计

ps:OCS完整介绍

  • 1.3 ReactNative
    React Native 让开发者使用 JavaScript 和 React 编写应用,利用相同的核心代码就可以创建 Web,iOS 和 Android 平台的原生应用。React Native 的宗旨是,学习一次,高效编写跨平台原生应用。

    • React Native有什么优点
      • 提供了原生的控件支持
        使用 React Native 你可以使用原生的控件,入在iOS平台我们可以使用UITabBar控件,在Android平台我们可以使用Drawer控件。这样,就让我们的App从使用上和视觉上拥有像原生App一样的体验。而且使用起来也非常简单。

      • 异步执行
        所有的JavaScript逻辑与原生的代码逻辑都是在异步中执行的。原生的代码逻辑当然也可以添加自己的额外的线程。
        这个特性意味着,我们可以将图片解码过程的线程从主线程中抽离出来,在后台线程将其保存在磁盘中,在不影响UI的情况下计算调整布局等等。

        所以,这些让React Native开发出来的App都是较为的流畅。
        这个之间的通信过程也是有序列化来完成的,这个就让我们可以使用Chrome Developer Tools 来完成JavaScript逻辑的调试,当然我们也能够在模拟器和物理设备上调试。

      • 触屏处理 React Native实现了高性能的图层点击与接触处理。

      • Flexbox的布局样式 使布局将变得更简单,这就使我们为什么要将网页的布局模式切换到React Native的Flexbox布局模式。Flexbox让UI布局变得简单,入使用margin和padding的嵌套模式。当然,React Native 同样也支持网页原生的一些属性布局模式,如FontWeight之类的。这些声明的布局和样式,都会存在内联的机制将其优化。

      • Polyfills机制 React Native也支持我们使用第三方的JavaScript库,来方便我们的开发。支持npm中的成千上万的模块。

      • 基于React JS 拥有React JS的优良特性。

2. 抉择

通过上面的简单介绍,可以看出DynamicCocoa和OCS都还是很厉害的。对于iOS开发人员,可以不需要去花费过多的时间来学习其他语言,使用原生的Object-C也可以基本完成动态化。然后在实际开发中,以及实际的项目中,功能不仅仅是在iOS平台上面,同时在Android中也需要。这个时候就比较尴尬了。但是ReactNative却不一样,他是跨平台的,可以同时支持iOS和Android,同时可以达到原生的效果(虽然和其他两个的性能上还是有些差距),而且现在的手机性能都在不断提升,利弊权衡下,个人觉得ReactNative相对是更优选择。

3. ReactNative应用

这里主要相对于现有工程

  • 3.1 在现有工程中添加ReactNative
    条件:
  • 1、CocoaPods
  • 2、Node.js

步骤:

  • 1、工程根目录下创建ReactComponent
  • 2、在ReactComponent目录中创建JS文件(例如:index.ios.js),并初始化
npm init
  • 3、通过CocoaPods安装ReactNative库
def react_native
    # 取决于你的工程如何组织,你的node_modules文件夹可能会在别的地方。
    # 请将:path后面的内容修改为正确的路径(一定要确保正确~~)。
    pod 'React', :path => ‘./ReactComponent/node_modules/react-native', :subspecs => [
    'Core',
    'ART',
    'RCTActionSheet',
    'RCTAdSupport',
    'RCTGeolocation',
    'RCTImage',
    'RCTNetwork',
    'RCTPushNotification',
    'RCTSettings',
    'RCTText',
    'RCTVibration',
    'RCTWebSocket',
    'RCTLinkingIOS',
    ]
end
  • 4、执行CocoaPods
pod install
  • 5、添加原生代码
NSString * strUrl = @"http://127.0.0.1:8081/index.ios.bundle?platform=ios&dev=true";
    NSURL * jsCodeLocation = [NSURL URLWithString:strUrl];
    
    RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                        moduleName:@"AwesomeProject"
                                                 initialProperties:nil
                                                     launchOptions:nil];
    self.view = rootView;
  • 6、运行react
npm start
  • 7、运行原生应用(Run)

4. ReactNative发布

在技术上来讲当然可以把react程序放在服务器上,但是加载速度就比较慢,在用户体验上当然也会减分不少。因此可以通过打离线包(jsbundle)的方式,通过服务端控制来实现程序的动态化(类似JSPatch发布机制)。

  • ReactNative离线打包
    我们用‘react-native bundle’命令把JS代码打包成一个bundle文件。然后客户端直接访问这个bundle文件即可。
命令说明
react-native bundle

Options:

命令 枚举 解释
--entry-file index.ios.js 入口文件
--platform "ios"/"android" 平台
--transformer /packager/transformer.js transformer
--dev false /true 调试开关
--prepack false/true
--bridge-config
--bundle-output 路径 bundle包目标路径
--assets-dest 资源文件路径 资源文件路径
  • 修改原生代码
NSURL * jsCodeLocation = [[NSBundle mainBundle ] URLForResource:@"main" withExtension:@"jsbundle"];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"AwesomeProject" initialProperties:nil launchOptions:nil];
self.view = rootView;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容