你好 我的名字叫Azat Zulkarnyaev,我在Badoo开发iOS应用程序。 创建移动应用程序时,大部分时间都花在了开发UI上,而优化此过程始终是开发人员中的热门话题。 我的同事亚历克西斯·桑托斯(Alexis Santos)写了一篇文章,内容涉及我们在执行此任务时遇到的问题以及如何朝着解决这些问题的方向迈进。 我决定与您分享翻译。 我还建议您观看Igor Savelyev在Mobius 2018上最近报道的录音。几个月前,我遇到了Netflix的一个非常有趣的纪录片系列-“抽象:设计的艺术”。 它详细介绍了来自各个领域的设计师的工作:建筑,图形设计,时装等。很容易注意到他们的工作与参与用户界面实现的iOS开发人员的活动存在某些相似之处。 尤其是在进行大型项目时,设计师会尝试按照“分而治之”的原则将其分解为许多小任务,并有机会在以后的阶段将所有元素组装在一起。
这种分离使得可以专注于特定问题,而无需考虑组件的互连。 不过,您无法完全忘记全局,否则,当组装时间到来时,可能会遇到困难。
另一方面,在观看过程中,我注意到许多产品(鞋,海报或建筑物)的最终设计都不会随时间变化。 耐克公司将新的运动鞋送到货架上,将不再更新外观。 在某些情况下,该产品在20年后仍然看起来不错。 不幸的是,幸运的是,该原理不适用于移动应用程序的设计-开发人员必须为频繁更改其产品外观做好准备。
帝国大厦(纽约)Nike Air Max 97许多从事大型复杂应用程序的iOS开发人员都花费大量时间来创建界面,定义对象关系和细化细节。 为了进行有效的工作,有必要牢记整个应用程序的外观,考虑将其划分为独立的组件同样重要,这些组件随后在开发应用程序元素时将被重用。
我们的团队每周都会发布新版本,每个版本都包含会影响用户界面的新功能,改进和其他更改。 我们始终致力于尽快高效地工作,但是在一年前,在开发UI时,发现了一些问题。
发行
简而言之,我们UI的开发过程结构不清晰。
实际上,这意味着启动任何新功能都可能导致最不可预测的后果。 例如:
- 与设计师进行互动没有明确的规则:同事们并不总是了解我们的工作,这导致他们创建了新的组件,实际上与现有组件相似,但外观有所不同。
- 我们没有用于实现新UI组件的通用模型:每个开发人员都以自己的方式实现了这些组件,这使项目的支持变得复杂;
- 代码重复也没有使代码库更好。
结果:
- 要更改一个UI元素,有必要在项目的许多地方更改代码;
- 如果更新与更新无关,并且未测试其工作,则增加了破坏应用程序各个部分的风险。
当然,所有这些问题都无法通过魔术解决。 为了改变事物的顺序,有必要在各个团队之间达成协议,并说服过程中的所有参与者都必须进行改变。
顺便说一下,“分而治之”的原则。 我们一个接一个地解决了一些小问题,然后逐步解决了全球性问题。 下面我将告诉您我们是如何做到的。
UI框架
我们非常认真地着手解决问题,从基础开始。 首先,有必要摆脱代码重复。 为此,我们将使用的组件统一起来。
我们决定创建几个称为BadooUIKit的框架。 根据我们的想法,它们应包含所有必需的UI组件(例如Apple的UIKit)。 每个框架类都对应于应用程序的UI元素(我们公司正在开发其他应用程序,但是在此UIKit中,我们仅添加了Badoo中使用的组件)。
每个应用程序都有自己的字体,颜色,边距和其他属性,因此,拥有与特定应用程序相关的样式表非常有用。

但是,如果一个或另一个UI组件可以在不同的应用程序中使用怎么办?对于这种情况,我们创建了另一个框架-Platform_UIKit。 它包含适用于其他应用程序的所有组件。
您是否刚刚将所有UI都立即转移到了新框架?不,这很成问题。 取而代之的是,我们在框架内创建了每个新的UI元素,并且仅当我们在执行任务的过程中触摸它们时才转移现有组件。 有时由于过多的依赖关系而导致组件难以迁移-然后我们单独进行了处理。 首先,我们转移了字体,颜色和按钮等基本元素。 然后,建立了基础,我们将聊天的整个界面转移到了框架中。 为简化起见,我们在创建基础结构之后进行了此操作。
主题:如果您对创建组件的过程感兴趣,请阅读 我的同事Valery Chevtaev myltik的精彩文章 。
框架的主要要求之一是缺乏对与UI无关的其他框架和类的依赖。 特别是,我们从不从主应用程序,与网络层有关的类,分析等导入模型。因此,我们有机会重用组件:

我们可以将数据从Platform_UIKit导入BadooUIKit,反之亦然:Platform_UIKit必须保持独立。

创建这些框架并不需要太多的工作以及随后的支持。 每个新的Badoo项目都与先前的项目不同,因此我们很难维持所描述的结构,但是我们的解决方案在短期和长期都受益。
使用UIKit的优点:
- 将所有UI组件存储在一个位置,使它们更易于查找; 因此,工作变得更有条理;
- 从依赖中释放类有助于减少编译时间;
- 消除依赖关系有助于组件的重用,并加快编译速度;
- 更新BadooUIKit中的组件,我们到处都进行更新; 如果应用程序使用BadooUIKit中的组件,则简化了整个应用程序中对组件进行更改的过程;
- 隔离的组件更容易测试;
- 如有必要,可以在其他应用程序中使用单独的框架(例如,在创建应用程序时-该框架所有组件的目录)。
创建Badoo画廊
BadooUIKit帮助我们解决了很大一部分问题,但我们知道完美无止境。
如何分别查看所有UI组件? 我可以自定义组件搜索并以不同的配色方案查看它们吗? 可以促进他们的测试吗? 是否可以为设计人员创建所有现有和已实现的UI组件的目录?
通过启动BadooUIKit,我们决定创建一个简单的单独应用程序目录以供内部使用。 因此,这里有Badoo画廊。
Badoo Gallery是一种工具,可以帮助开发人员,设计人员甚至产品团队的成员以清晰易懂的方式查看所有UI组件。 创建它时,我们使用了多种工具来促进与组件的交互。
由于我们的应用程序不打算在App Store上发布,因此我们可以添加我们认为必要的任何工具。 作为关键,我们确定了以下功能:
- 元件搜索;
- 按名称对组件进行排序;
- 将项目添加到收藏夹
- 在样式之间切换-这样您就可以看到组件在特定设计中的外观;
- FLEX ;
- FPS计数器。

根据用户的操作和应用程序的内部逻辑,每个组件可以处于不同的状态。 例如,UIButton具有五种状态:1)默认状态,2)突出显示,3)悬停,4)单击和5)锁定。
有意思吗
在这里阅读更多。
此外,我们希望能够在一个地方展示所有可能的组合-我们在每个组件的每个屏幕上都这样做。 当然,我们按钮的状态可能与UIKit Apple按钮的状态不同。

Badoo Gallery的主要优点:
- 创建已实现的UI组件列表的能力;
- 轻松搜索UI组件:我们每个人都可以看到UI组件外观的所有可能选项,并为其找到应用程序;
- 对现有组件的轻量级搜索有助于说服设计人员重复使用它们;
- 如此小的应用程序的编译时间非常短,有助于显着缩短开发周期。
- 收藏夹功能有助于查找当前已实现的组件;
- FPS,FLEX和MultiBrand等外部工具的添加使您可以衡量和改进UI组件的质量;
- 所有组件都放置在单独的框架中,并在隔离的环境中显示-测试变得更加容易。
关于测试的一点
新工具帮助解决了本文开头所述的大多数问题,但仍有一些问题尚未得到解答。



我们可以确定所做的更改之后,UI会看起来像我们想要的吗? 如何保护应用程序的组件和其他部分免受子组件新参数的不利影响?
找到这些问题的答案将有助于测试UI组件。 网上有很多关于iOS上的UI测试组织的文章。 此外,还有许多旨在测试界面各个方面的工具。
我们决定通过引入最流行的开源实用程序之一iOSSnapshotTestCase(以前称为FBSnapshotTestCase,因为它由Facebook创建)来进行快照测试。
您可以使用以下链接之一来了解有关使用屏幕截图进行测试以及有关此框架的更多信息:
我们需要一种方法来测试BadooUIKit中已经存在的组件,以避免在更新应用程序组件时出现退化。 我们还希望最大程度地自动化引入新快照测试的过程。
之前,我谈到了我们创建的库,其中包含所有组件的列表以及每个组件可以接受的状态。 这非常方便,因为在这种情况下,可以基于Badoo Gallery作为宿主应用程序运行测试。
BadooUIKit中的所有组件都包含在存储库类中,该类提供对所有组件的访问。 该存储库既可以演示库中的组件列表,也可以使用快照测试类打开对它们的访问。 这使我们摆脱了创建对象和为每个组件准备不同状态的双重工作,因为当我们将组件引入图库时,所有这些工作都已经完成。
以下是有关使用快照进行测试的最常见问题的答案。
快照存储在哪里?我们将它们直接存储在Git存储库中。 我们担心这可能导致其膨胀,但实际上一切都还不错。 通常,我们会测试小的组件,因此屏幕截图的权重很小。 目前,带有屏幕截图的文件夹大约需要11 MB,我们认为这是可以接受的。
您是否正在所有可能的环境中测试所有可能的权限?不,这种方法的好处很少。 但是可能存在很多问题:测试将变得不可靠,带有快照的文件夹将变得越来越庞大,并且测试套件将变得更加难以支持。 我们仅对最流行的设备进行实用的测试。 此外,我们的CI系统配置为使用与创建快照相同的模拟器。
快照测试可以覆盖整个界面吗?我认为不是。 Badoo我们针对不同级别的应用程序执行各种测试。 例如,功能(使用Calabash和KIF框架)和集成。
结论
当然,在构建新平台的过程中,我们学到了很多东西,并且继续学习。 上述工具和流程大约在一年前出现,并且仍在发展中。 在这个阶段,我们可以得出结论,它们对开发人员和整个公司都有利。
以下是我们在工作过程中吸取的一些教训:
- 转移所有现有组件并不是一件容易的事,但是通过实施设计系统并促使团队使用它,您将看到组件的数量如何快速增长:开发人员使用的组件的转移不仅自动增加了系统中可重复使用的UI元素的数量,而且还帮助释放了现有元素。来自依赖 将来,这将允许传输更多组件;
- 设计师喜欢重用组件(说服他们这样做很容易,因为有可能展示出满足其要求的功能完备的组件);
- 节省时间是必要的; 我们都知道,在Swift和Objective-C上编译项目的持续时间有很多不足,而Badoo Gallery应用程序是轻量级的,并且编译速度非常快。 我们意识到,直接使用图库来实现UI组件,然后在编译不是那么快的主应用程序中使用它们,将更加方便。
- 通过组合UIKit中的所有组件并启动可以对其进行测试的Gallery应用程序,我们使整个测试过程变得更加高效和轻松。
下一步-宇宙
我们非常关注我们的每种产品,并希望它们都具有通用且有吸引力的界面。 为了使我们的用户尽可能地享受其使用,我们决定进行全球更改。 在设计师和产品团队的协助下,我们正在引入一种新的统一设计系统,称为Cosmos。
克里斯蒂亚诺·拉斯塔利(Cristiano Rastelli)写了一些有趣的
文章 ,介绍了宇宙系统是如何产生的。 不要错过!
致谢
这个项目的工作是由一个以上的人进行的-在某种程度上,整个Badoo iOS团队都参加了该项目,包括经理,开发人员和测试人员。 我感谢他们所有人,因为他们每个人都是从旅程的一开始就加入的。
感谢我们出色的设计师,他们时刻准备着尽一切努力来改善设计过程。
特别感谢
Alexander Zimin :进行了许多建议的改进,拜访了无数的滑翔机,以及这次冒险为我提供的支持。
我还要感谢
Alissa Ordigliano出色的插图,使本文更易于使用。