模块化iOS应用程序时的常见问题

您可能想模块化您的iOS应用程序,但是在某些情况下,事情可能会变得复杂起来 。 在这篇文章中,我将介绍在对现有的大型iOS应用进行模块化时遇到的最常见的问题,以及为解决避免这些问题而采取的措施。

本文将主要介绍封装循环依赖项, 图像 (捆绑), pbxproj以及将现有应用程序部分提取到框架中。

“好吧,我要在哪里创建这个?”

当您的应用程序中有框架时,您可能会想到的第一个问题是“您将在哪里为下一个功能编写代码?”。

正如我在上一篇有关框架的文章中所说的那样,您应该对框架进行分类。 您可以拥有一个Core框架,一些特定于功能的框架以及其他一些技术框架。
如果您的新功能或要开发的功能没有输入任何现有框架,则可能需要创建一个框架。

谨慎选择因为如果您想更改此新功能或与该新功能交互 ,它肯定会在以后产生影响

“公共的,内部的,私人的?”

在您的鼻子前看到这个弹出窗口! 这是因为您需要声明您的类/结构或您在模块中定义的任何内容,并希望以public的形式外部 访问它。

在开发不带框架的应用程序时,您通常不会过多地关注可见性或访问控制,因为默认情况下,Swift中的所有内容都是internal 。 内部意味着您可以在当前模块中访问它。 在开发模块时,需要从外部将要使用的类显式定义为public

这也迫使您拥有更好的代码封装并更好地定义应用程序结构 。 您只应将希望从框架外部 访问的类型标记为公共 。 其他所有内容至少应该是内部的 ,或者甚至是私有的(如果用于本地)。

因此,如果您想消除Xcode错误,只需将您的类标记为public即可

“让我们在需要的任何地方导入此框架!”

对,但是 ! 使用框架时,您必须要小心,否则您将面临循环依赖和许多麻烦 。 在您的框架内,您不能导入已经 直接间接 导入第一个框架的第二个框架。

另外,您可能会遇到这样的情况,即功能框架(假设为Account )想了解有关另一个框架( Booking )的一些知识,以创建链接。 例如,您想根据您在“ 帐户”部分中的 偏好启动预订搜索 您想从帐户框架中启动搜索,因此您可能要导入Booking框架,但这是错误的,因为这将质疑这两个框架的分离。

那么,如何处理不应相互导入的两个框架之间的链接 ? 这种情况是一个有趣的问题,一种解决方案是使用称为POP (面向协议的编程)的模式在两个框架之间建立桥梁

解决方案需要很长的篇幅进行解释,因此在这里我不再讨论,但是我肯定会在一篇文章中讨论。

“加载图像时,我的应用程序崩溃了!”

如果您要提取具有许多图像的应用程序的现有部分,将会给您带来麻烦。 每个框架都有自己的捆绑包 ,这意味着,如果您将图像放入framework.xcassets并正常地在.xib.storyboard或什至使用#imageLiteral中 加载图像,最终将发生以下崩溃

该应用程序崩溃是因为xibs情节 提要imageLiterals使用的捆绑包主要捆绑包 。 由于您是在具有自己的捆绑软件的框架中进行开发,因此系统正在错误的捆绑软件中查找图像资产。

解决此问题,必须为在此框架中使用的每个图像 指定捆绑包。 这是您可以做的事例:

当我开始模块化我正在开发的应用程序的一部分时,我遇到了麻烦 。 我正在尝试导出一个小服务,该服务实际上是在使用另一个服务,该服务依赖于另一个服务……依此类推。

由于依赖关系,不可能将所有这些服务导出到我的新框架中。 它与主应用程序过于紧密联系,例如,如果您试图从面条中取出面条,但结束整个过程。

因此,我不得不找出如何导出我的第一项服务而又不抓起整个面条的菜。

我将在另一篇文章中详细解释我是如何做到这一点的,因为它需要清楚的解释,并且对于这篇文章可能会太长。

“碰上pbxproj……脖子痛!”

是的 ! 如果您是该项目的 多个开发人员,那么您将面临这个地狱 。 不幸的是,对于这个问题,我没有任何奇迹般的解决方案。

每次创建新框架或文件移动到其他目标时 ,或者基本上每次触摸一个目标的配置时,都在修改.pbxproj文件。 这意味着您将与队友发生冲突 ,并且此文件很难阅读 。 通常,您必须“ 选择两者 ”,但是您肯定必须检查项目是否中断

但是,有一个名为XcodeGen的工具可以解决此问题。 你可以在这里读更多关于它的内容。

总而言之,对于这个问题我没有任何实际的解决方案 ,但是请记住,仅在创建框架结构开始时 ,此文件上的冲突数量才很重要。 一旦定义了 框架 ,一切都应该可以正常工作,而您将不再遇到这种噩梦!

您可以检查GitHub项目,显示一个模块化的 iOS应用程序,我在本文中遇到的基本问题以及如何处理它们(例如图像和捆绑包 )。

我希望这篇文章能给您概述 模块化 iOS应用程序时可能遇到的主要问题。 所有这些问题都可以克服,所以继续吧! 😉