1. iOS模块化第2部分:将工作区分解为模块
如果你还没有读过本系列文章的前一部分,请点击这里:iOS模块化第一部分:扼杀iOS Monolith。在前一篇文章中,我讨论了模块化体系结构的好处,希望从视觉效果中可以明显看出这一点!
在这篇文章中,我将分享如何划分你的工作空间(workspace)。
1.1. Add your project to a workspace
如果您还没有一个工作空间,那么从现有的项目创建一个工作空间是非常简单的。(如果您是CocoaPods用户,您可能熟悉在首次安装依赖项时自动创建的工作区。)
从现有的项目中创建一个工作空间,在Xcode中打开项目,选择File→Save as workspace…
(如果该选项被禁用,这意味着您的项目已经是工作区的一部分!)
选择一个合适的位置来保存.xcworkspace包。这通常与表示项目的.xcodeproj包在同一个目录中。
现在您可以将特性模块添加到代码库中了!
1.2. Add additional projects
可能是你正在从零开始一个项目,想要遵循良好的实践。也可能是您希望对一个已经成熟的代码库进行模块化。无论哪种方式,您都希望在工作空间中创建一个额外的项目来开始。
-
Select File → New → Project…
-
Select Cocoa Touch Framework from the template options and hit Next
-
Give your feature module a name and hit Next
-
When selecting a directory to save your new module, you may wish to create a new directory, such as Features. It’s best to create the new directory in the same location as the .xcworkspace package
-
Don’t hit Create yet!
-
From the Add to: drop-down, select your workspace
-
From the Group: drop-down, select your workspace again. Make sure you’ve selected the workspace and not the project. You can tell because the workspace has a white background to the icon instead of blue
-
Now hit Create!
现在您有了自己的特性模块,您可以向其添加新代码,或者从现有项目中迁移代码。
如果你正在迁移代码,请确保将文件以及Xcode Project Navigator中的文件引用移到磁盘上。如果你使用Xcode来移动文件,请确保选择***Copy items if needed***。然后,你可以安全地删除原始文件和***移动到垃圾篓***。
1.3. Organise your workspace
默认情况下,Xcode会将每个新项目(模块)添加到项目导航器的顶部。因此,主项目——包含App Delegate的项目——出现在你的特性模块下面。
将添加的项目移到主项目下方是一个很好的实践,这样当开发人员打开您的工作区时,主项目是最重要的。
从Xcode 9.3开始,你可以在工作区中拖放框架项目。您还可以通过在Project Navigator中二次单击并选择New Group来添加组。

在Xcode 9.3之前,在工作空间中移动框架项目时Xcode会崩溃。
如果你创建了一个组并添加了一些模块,你的Project Navigator看起来就像这样:

1.4. Accessing code from your modules
任何想要从主应用程序访问的代码,都需要声明***public***。(Swift接口默认为内部接口。)
要从你的主项目访问模块的公共接口,你需要链接框架并嵌入框架二进制文件。
为此,选择主应用程序target和General选项卡。向下滚动到Embedded Binaries部分。单击+按钮。
您将看到如下所示的对话框,您可以从中选择想要访问的模块。您可以一次选择多个,通过命令选择,然后点击添加。

通过将它们添加到嵌入式二进制文件(Embedded Binaries)列表中,它们也被添加到链接框架和库(Linked Frameworks and Libraries)列表中。它们需要同时具备:

你现在可以像导入任何系统或第三方模块一样导入你的代码:
import UIKit
import Common
import ProfileUI
1.5. Clean up the Project Navigator
你会注意到这些框架已经被添加到Project Navigator中,在主项目下,就像这样:

让它们像这样暴露在外面感觉有点乱,尤其是当你添加越来越多的时候。我们可以通过创建一个“Frameworks”组并将它们移动到那里来清理这个问题,就像这样:

然后你就可以瓦解这个小组,再也不看它了!🙈
1.6. Coming up next
在本系列的下一篇文章中,我将展示如何从模块设置单元测试,以便在为主要目标运行测试时运行;如何设置CocoaPods,以跨模块化代码库使用这样;以及如何在模块之间共享测试逻辑。