iOS Swift - 运行 一个特定的 VIPER 模块,无需浏览所有屏幕

iOS Swift - run a specific VIPER module without navigating through all screens

我想在我的项目中使用特定的 Viper 模块。从技术上讲,现在当我需要打开一个特定的 UIViewController 时,我需要通过一些屏幕输入一些数据等等,然后在 20 秒后我就会进入那个特定的屏幕。

所以当我只需要例如测试一些小东西(比如 UI 调整,改变一些字符串如何适应屏幕等)时,导航某个地方需要花费很多时间。

相反,我想 运行 当我 运行 我的项目时的特定屏幕。

在这种情况下,模拟和注入肯定会有很大帮助,因为我需要用一些初始数据来填充我的 Viper 模块。这只是一个技术细节。

我想知道如何将我的项目组织到 运行 个特定模块而不是 运行 整个项目。

硬编码解决方案,例如通过添加覆盖初始点的额外代码来使用 app delegate 这只是一个临时解决方案,您需要在完成后清理 app delegate。

我可能错了,但我认为应该有一个特定的目标解决方案,它可以 运行 不同的模块,无论它是像 HomeViewController 这样的初始点还是带有模拟注入的特定模块。

为了设定这个答案的基本规则,https://TheSwiftDev.com/the-ultimate-viper-architecture-tutorial 描述了 VIPER 是什么的最规范的原始思想变体,以及它作为自律的目的。 (在过去的几年里出现了其他派生观点,但出于一箭双雕的清晰度和教学原因,我将在此答案中使用这一原始思想流派。)

  • 我要礼貌地拒绝OP对VIPER使用“模块”。相反,VIPER 是 5 zones {view for UI,interactor for datastore/networking/sensors,app-domain 'business' rules 的 presenter,app-domain-centric 的实体[不是以数据存储为中心,不是以网络为中心,不是以传感器为中心]数据结构,导航路由器}隔离和某种程度的分离。有人可能只是说区域和模块是 100% synonyms/congruent,但我将把它们分开作为单独的解释。 5 个 V I P E R 区域都是关于彼此 divorce/quarantine 以消除 Massive View Controller antipattern/code-smell 软件架构 https://khanlou.com/2015/12/massive-view-controller and https://www.hackingwithswift.com/articles/159/how-to-refactor-massive-view-controllers, which is a mobile-app variant of the older-era Big Ball of Mud antipattern/code-smell software-architecture http://www.laputan.org/mud/mud.html#BigBallOfMud

  • 另一方面,模块可以解释为比 5 V I P E R 区域更细粒度。让我们在这里做。 VIPER 的每个区域都可以进一步细分为该区域的类似主题部分的模块,例如包含 scene/screen/containing-view 的所有(子)视图或一个人内心想要的应用程序的任何其他子类别。模块分界可以与 5 V I P E R 区域正交(或无视)。事实上,设计人员可能会选择在 2 个或更多 V I P E R 区域中的每一个区域中进行相同的模块划分。或者同样有效的是,设计师可能会选择在视图区内与交互区内和演示区内进行完全不同的模块划分,因为他们每个人都偶然地专注于分解 isolated/divorced/quarantined 区域的不同方式只有在该区域内才有意义的方式(并且在其他一些 4 个区域内几乎没有意义)。因此,从这个答案的角度来看,我们不会再提及模块,因为它是每个区域的本地口味,与 OP 的预期目标无关。

  • 正确实现的 VIPER 架构中的每个区域都已被隔离,因此 UI 特定主题永远不会逃出视图区域(例如,进入最诱人的演示者区域或路由器区域或[通常是一个较小的诱惑,除非大量模仿传感器或网络数据采集的非 VIPER 示例]交互区)。由于这种隔离,OP 的目标实际上是拥有一个完全不同的 router/navigation 区域,通过其各种 scenes/screens/modal-dialogs 以一种甚至可能对人类不自然的方式在测试模式下驱动应用程序-应用程序的用户变体及其路由器导航。但是 VIPER 软件架构的 entire 长期目的是换出整个区域,因为它具有如此完美 quarantine/divorce——字面意思就像通过婚姻离婚将一个配偶换成另一个配偶.这就是 OP 正在有效寻求的:批发交换(主要)路由器区域的人类用户变体与测试模拟路由器区域,该路由器区域通过类似脚本的行进命令驱动应用程序以行进 UI 通过人类用户 UI 操作需要花费太多精力才能完成的方式。 mocked/scripted 替代路由器区域可以自由地“短路”,因为它愿意跳过 UI 的部分,只要本应自然建立的任何累积状态作为模拟的一部分回填照本宣科。如果路由器在短路导航到 UI 的 portion/screen/scene 时无法访问完成累积状态回填所必需的任何 methods/API,则 a) 分离问题被消除,因此 mocked/scripted 替代路由器区域比其常规人类用户变体隔离得更少,或者 b) 其他一些区域需要某种程度的模拟来回填罐装累积状态以与 mocked/scripted 合作替代路由器区域。

  • 但是要完成通常的路由器区域与 mechanistic/test/mocked 路由器区域的换出,以实现 UI 的类似脚本的导航,交互区域尤其必须是mocked 也以类似脚本的方式以及与 testing/mocked 路由器变体合作的方式驱动固定数据存储内容、固定网络内容和固定传感器 content/acquisition。事实上,quarantine/divorce 在应用程序的普通应用程序域人类用户变体中如此受追捧是奖品,但更少的隔离也许根本不离婚可能是 [=66= 之间值得称赞的目标] 路由器区域和 mocked/testing 交互区域,它们可能会非常紧密地结合在一起,作为一种思维方式一起完成它们的 scripted/canned 模拟功能。因此,对于应用程序的人类用户主要变体而言,什么是好的 divorce/quarantine 关注点分离可能在应用程序的 OP mocking/testing 变体中是灾难性的分离,因为实际上没有这样的分离scripted/mocked 路由器区域替换为 scripted/mocked 交互器区域替换为

    之间的关注点
  • 人们希望演示者的业务规则类后端式处理不需要被模拟出来,因为希望那些应用程序域业务规则的执行不会得到在 UI 的机械驱动方式中 1) mocked/scripted 通过替代路由器区域进行导航和 2) 使用来自 mocked/scripted 传感器的 mocked/scripted 数据,mocked/scripted数据存储,and/or mocked/scripted 网络。如果某些应用程序域需要将视图区域中的纯 UI 测试与演示区域中的纯 business-rules/quasi-backend 测试分开,那么模拟的 UI 视图区域将 test/drive 真实演示区和模拟业务规则演示区(可能有 alternate-reality/fuzzed 业务规则)将 test/enforce-more-strictly 真实视图区。

  • 相反,如果一个应用程序的开发者未能 100% 隔离,比如说,UI 视图区内的主题,那么能够换出 UI-污染的非视区可能被致命地侵蚀到无法用 testing/mock 非视区替代品替换非视区的程度。要在 V I P E R 区域之间实现这种 100% 严格的隔离区域间需要公开的自律,以确保 100% 的区域间 messaging/method-invocation 以纯粹的应用程序域概念表达,而不受 Apple-think 或其构造的污染,Android-思考或其概念,等等。每个 V I P R 区域(除了 E 中相当简单的实体)通常需要在每个区域的周边有一个外观层,以便将区域内概念与应用程序域间概念交互,例如隔离所有 Apple-think UI 构造或 Android-think UI view zone 中的概念,以便只有高阶思想的应用程序域概念在 interzone 之间交换——同样在 interactor zone 周边有一个 façade,用于交互隔离以数据存储为中心或以传感器为中心或以网络为中心构造 intrazone 远离高阶思维应用程序域概念 interzone。

  • 同样,代替全自动脚本导航,另一个 testing/mock 路由器导航区域的替代品可以将人类用户快速转发到特定的 portion/screen/scene UI 用于半自动测试的手动交互。快进可能是相对空缺的screen/scene。或者快速转发可以是,比方说,一个编辑屏幕,其中包含精心制作的实体以供编辑,如果精心制作的实体在执行某些用例或正确的情况组合时特别有害,这将特别有用错误再现。