可汗学院向反应原住民的转变

2020-07-11 23:58:09

2017年,可汗学院开始在我们的iOS和Android应用程序中使用Reaction Native。从今年1开始,我们已经达到了一个重要的里程碑:我们向Reaction Native的过渡已经完成!应用程序中的每个屏幕都在Reaction Native 2中渲染。

iOS和Android应用程序的设计几乎相同,交互方式相似--设计、功能和内容。

维护两个代码库是具有挑战性的,因为开发新功能需要不同的数据设计、错误和协调。(请立即详细介绍这一点。)。

我们的移动团队规模很小,所以过渡不需要协调大量的工程师。

我们的网站已经在使用Reaction,所以我们在内部拥有帮助过渡的概念和工具的专业知识。

让我们更多地讨论维护两个独立代码库的挑战:

不同的错误会出现在不同的平台上。当然,“原生反应”也是如此,但这种情况要少得多。

实现新功能需要跨两个平台协调设计、工程和测试。这意味着你至少需要两个工程师(iOS&;Android),理想的情况是同时有空--对于我们这样一个小团队来说,这是很难做到的!

一旦构建了功能,就很难更改,因为您必须在两个平台上都更改它。很难调整和更新设计。

不同平台之间的架构差异很大。我们的iOS代码库比Android代码库老了四年。iOS有SWIFT、ReactiveCocoa、Cartoography和CoreData。Android有自己的一套依赖项和数据流设计。这里的不同之处加在一起-从其他平台借用一个功能通常并不简单,而且审查另一个平台的代码也不容易,所以我们的工程师基本上是按平台孤立的。

过渡基本上分为三个阶段:探索、跨越和灭绝。(巴斯坎普的山图就是一个很好的比喻。)。

探索(2017年初)是在原生代码和Javascript代码之间添加桥梁的早期工作,我们在Reaction Native中的第一个屏幕,比如搜索选项卡。几乎所有的网络、数据、业务逻辑和所有“客户端后端”的东西都是通过一座桥传递的。这涉及到大量的样板文件,因此相当单调乏味。

跨境(2017年年中至2018年年中)肯定是最难的。我们已经决定使用“反应原住民”,但离终点线还很远。我们现在有三件事要考虑:原生iOS、原生Android和Reaction原生代码。工程师需要知道两个(或更多)范例才能进行更改,而且还有很多东西需要学习!

灭绝(2018年年中至2020年年中)是我最喜欢的部分。这一阶段从我们的“流式主题树”项目开始,这是一个历时数月的项目,我们将内容数据库(我们的许多课程、视频、文章和练习)从一个大型捆绑的本机数据库(例如CoreData)完全过渡到一个用Javascript编写的轻量级缓存库。既然我们的客户端内容数据库已经在Reaction Native中,我们几乎不需要通过我们已经构建的桥传递那么多内容,并且可以开始删除大量的本机代码。今年的V7.0版本是升级我们最后一个原生屏幕以响应Native的最后一次努力,同时统一了手机和平板电脑的导航设计。

我们对“屏幕内容”使用响应原生代码,对这些屏幕周围的导航使用原生代码。有几个潜在的原因,但本质上是“复杂的实现在哪里”和“是什么让本地应用程序感觉本地”之间的平衡。

我们应用程序的绝大多数“业务逻辑”都存在于屏幕内容中(比如主页选项卡的内容,或者书签选项卡的下载规则)。相比之下,选项卡栏或导航栏的内容不太依赖于业务逻辑。

然而,在Reaction Native中编写的导航栏和导航控制器在一些小的方面感觉是假的,这一点加起来就是假的。原生导航控制器为我们提供了正确的滑动返回手势,以及推送/弹出动画的正确动画计时。原生导航条可以轻松处理开槽的iPhone。将每个屏幕包装在原生UIViewController中还可以在需要时为我们提供屏幕生命周期中熟悉的位置。(有一些库一直在努力模拟系统标准导航栏;我们还没有找到满足我们需求的库。)。

当我们在2017年开始这项实验时,我们的规则是这款应用程序必须仍然“感觉”是原生的。当然,有些地方它是不完美的,但我们相信,我们所做的妥协让我们能够在许多其他方面极大地改进我们的应用程序!

这款移动应用程序的翻译有两部分:内容和平台字符串。内容字符串来自我们的内容管理系统;示例包括交互式练习中的问题、视频的内容和字幕或文章中的文本。(这些内容字符串中的许多都是我前面提到的“流式主题树”的一部分。)。平台字符串在移动应用的代码库中定义;示例包括“注册”按钮中的文本、选项卡栏项目的标题或设置屏幕中显示的文本。

我们有一些优秀的自制基础设施来维护平台字符串。您在JavaScript中定义了一个字符串,我们已经构建了将该字符串复制到原生iOS和Android字符串的脚本。这非常有帮助;我们可以很容易地跨Native重用字符串,并毫无问题地响应Native,这在那个“跨”过渡期非常有帮助。

从2015年到2019年,我们的应用程序只支持6个地区,但现在我们支持19个地区!iOS&;Android的共享实现帮助我们获得了流媒体主题树,这意味着添加额外的语言不会使我们的应用程序变大。此外,我们能够在Reaction Native中轻松设计处理非拉丁字符的组件。我们的移动团队不再是扩展移动应用覆盖范围的制约因素--重要的是我们是否有足够的(海量)内容库翻译到特定的地区。这对我们的国际倡导者来说是一个巨大的鼓舞;他们真的很兴奋能为世界各地的社区提供合适的移动应用程序。

这一部分更多的是个人观点,所以,呃,记住这一点!您的里程可能会有所不同。

迁移到Reaction Native并不是十全十美的-在此过程中遇到了一些坎坷,比如学习一门新的语言,一个新的组件生命周期,等等。“跨越”阶段特别具有挑战性;在桥接我们的本机代码和反应本机代码时,有很多乏味的样板代码!

在个人层面上,我怀念很多关于Swift的内容,特别是关联值枚举、方便的初始化式、命名参数,以及向结构和类添加函数和变量的简单性。

Reaction Native感觉比UIKit更具延展性;重塑和重构代码感觉很棒。例如,您为UICollectionView编写的代码与UITableView不同,与UIStackView不同-但在Reaction Native中,您只需使用…。不用担心吗?在很大程度上,您可以在重构时剪切和粘贴代码,并且将某些内容从网格更改为列表非常简单。(这项福利与SwiftUI的许多福利之间有很多重叠之处。)。

开发人员工具非常出色。Xcode是我作为一名开发人员出现的地方,所以我知道它的古怪之处,但我现在的真爱是VSCode。当然,这是一个需要学习的新词汇--但事实上,我有一个VSCode插件,当我点击保存时,它会自动格式化我的代码?难以置信!。有如此多的链条和自动修复程序,以至于我们的代码审查实际上并不涉及很多细微的样式指南修复:计算机正在为我们进行格式化,而且它感觉非常有帮助。

我正在制作一款Android应用程序,而我对编写Android应用程序几乎一窍不通!我知道可以添加额外的参数或函数,但我不是Android…的架构师。然而,我能够接触到更多的Android学习者,并为他们构建功能!这与我们的使命和我的个人价值观非常一致,能够参加这里的活动感觉非常好。

我觉得更愿意加入我们的网络前台。我本质上是一名移动开发人员,但现在我已经熟悉了response Native,在我们的Web应用程序上提供帮助并不是什么难事,我们移动团队中的一大部分人已经在做这件事了!扩展和探索Web开发感觉很棒(我们也有Web工程师为我们的移动代码库做出贡献!)。

我们的iOS和Android应用程序共享一个代码库,工程师们专门研究应用程序的功能,而不是平台。这意味着随着时间的推移,我们可以更好地改进给定功能的质量,我们可以对功能进行渐进式改进,而不是感觉需要在初始版本中获得所有东西。

共享基础架构使我们更容易过渡到GraphQL,而GraphQL反过来又简化了我们要进行的服务器端过渡。

我们的应用程序要小得多。从大型捆绑内容库数据库转换为流数据库,极大地减小了我们的应用程序大小。是的,这可以在本地完成,但是在一个地方实现比在两个地方协调更容易。

有了我们的网站,我们是一个更好的舞伴。在这一过渡期间,我们小心翼翼地使我们的移动设计类似于我们网站的信息设计,这简化了添加新的跨平台功能,如我们新的掌握挑战功能。当工程师感兴趣的时候,他们可以在网络和移动设备之间来回切换,这让我们感觉到与整个组织的联系更紧密了。(如果您是对可汗学院感兴趣的前台工程师,您将能够帮助构建我们的移动应用程序和网站的功能!)

我们在应用程序中仍然有原生代码,这太棒了!当需要时,我们可以跳回Xcode或Android Studio并实现特定于平台的功能,比如iPad多任务处理。

我们有一个强大的设计系统,可以帮助我们的设计师和工程师快速对我们的产品进行改进。对于移动设备,这体现在一些关键方面,比如拥有处理触摸高亮显示、可访问性、加载状态等的标准和预置组件。

现在可汗学院的主要工程项目是Goliath,在那里我们正在重新设计我们的后端,使其成为围棋服务的集合。我们统一的移动基础设施帮助我们完成了这一过渡:即使我们的移动团队只有六个人,我们仍然能够构建新的功能和修复!我们的应用程序可以更好地改进和扩展其功能、本地化、质量和性能。

在结束这里之前,最后一个警告:完全原生的应用程序也很棒,我们中的许多人仍然非常喜欢在其他项目中使用它们。(就我个人而言,我的心仍然属于Xcode,我真的很享受在SWIFT中思考!)。也就是说,我们向反应原住民的转变对我们的团队来说是一个巨大的恩惠。它不是每个人的唯一真正的选择,但它对我们来说非常有效!

我们怎么花了三年时间?我们有一个很小的团队,而且在很大程度上,我们在处理屏幕时只转换了屏幕。

嗯,几乎-每个屏幕。有一个一次性的Android语言选择屏幕,它不在Reaction Native中,而且我们没有迫切需要将其迁移到Reaction Native,所以它可能会停留一段时间!

多年来,移动团队的规模各不相同,但我们通常有大约六名移动工程师。