将 Swift 应用程序的组件划分为 Swift 模块

Posted

技术标签:

【中文标题】将 Swift 应用程序的组件划分为 Swift 模块【英文标题】:Dividing a Swift application's components into Swift modules 【发布时间】:2016-04-06 03:59:05 【问题描述】:

我正在用 Swift 编写一个 ios 应用程序,并试图弄清楚如何将项目组织成单独的模块。我正在使用 MVVM 架构,我想让 Model、ViewModel 和 View 组件分离 Swift 模块,使导入它们的模块只能访问它们自身的子集。 View 中的文件将导入 ViewModel,而 ViewModel 中的文件将导入 Model。我怎样才能做到这一点?请注意,我并不是要创建多个应用程序可以共享的库。我只是想使用模块来强制分离组件。

编辑:也许问题是,“除了最初的 iOS 应用程序项目附带的模块之外,我应该使用什么机制来创建模块?”

“如何在 Swift 中使用命名空间?”中的一个答案https://***.com/a/24032860/215400 说,“类(等)由它们所在的模块(Xcode 目标)隐式限定。”由此,人们可能会得出结论,目标对应于模块,答案是在 Xcode 项目中创建单独的目标,但我之前尝试过,tskulbru 说我需要多个 Xcode 项目。

关于多个 Xcode 项目,File > New > Project > iOS Framework & Library > Cocoa Touch Framework 选项看起来不正确,因为它应该用于使用 UIKit 的东西,而我要创建的两个模块应该'不依赖于 UIKit。另一个“框架和库”选项 Cocoa Touch 静态库不是 Swift 的选项。

另一个 *** 帖子提到使用私有 Pod。在花了一个小时研究之后,我得出结论认为这不是正确的解决方案,因为我不应该在不同的工作区编辑这些模块。

【问题讨论】:

How do you use Namespaces in Swift?的可能重复 为什么不使用private 限定符来强制封装? @Marc--谢谢,但将内容设为对它们定义的文件的私有不是我想要的。 Modules 提供的公共访问与内部访问 (developer.apple.com/library/ios/documentation/Swift/Conceptual/…) 正是我想要的。 @ChristopherSimmons “Cocoa Touch 框架”这个名称具有误导性,苹果可能出于市场原因选择了该名称。真的,它应该被称为“达尔文框架”或类似的东西。 “Cocoa Touch 框架”真正构建的是一个封装在 ….framework 中的动态共享库——它可以依赖于 UIKit 或 AppKit 或 Foundation 或 CoreFoundation 或任何其他框架,甚至没有依赖关系(仅依赖于 std /system C API)。要使其不依赖于 UIKit,请进入项目设置并将 Linked Frameworks 中的 UIKit.framework 替换为 Foundation.framework 【参考方案1】:

如果不为您要创建的模块创建单独的项目,这是不可能的。这是因为 Swift 处理命名空间的方式。

Eonil 回答得比我好:https://***.com/a/24032860/215400 (复制如下)

SevenTenEleven 在Apple dev forum 中回答:

命名空间不是每个文件的;它们是针对每个目标的(基于 “产品模块名称”构建设置)。所以你最终会得到一些东西 像这样:

import FrameworkA
import FrameworkB

FrameworkA.foo()

所有 Swift 声明都被认为是 一些模块,所以即使你说“NSLog”(是的,它仍然存在) 你得到了 Swift 所认为的“Foundation.NSLog”。

还有Chris Lattner tweeted about namespacing。

命名空间在 swift 中是隐式的,所有的类(等等)都是隐式的 由它们所在的模块(Xcode 目标)限定。没有类前缀 需要

【讨论】:

如果您复制其他答案的主要部分,请添加指向原件的链接以正确注明出处:***.com/a/24032860/1187415。 嘿,我实际上认为你的答案更接近我正在寻找的,tskulbru。如果我需要创建单独的项目,我应该怎么做?尽管我不需要 UIKit,我是否应该选择“Cocoa Touch Framework”选项?看起来“Cocoa Touch 静态库”会更有意义,但它不是 Swift 的选项。如上所述,我开始走私有 Pod 的道路,但这看起来不太好。 如果你想使用模块,你需要创建一个动态框架,如果你创建一个静态库,你需要将它包含在你的桥接头文件中,这会破坏整个事情的重点.有关如何创建动态框架的教程,请参见此处medium.com/@PyBaig/…【参考方案2】:

从我的角度来看,如果你想封装你的组件,可能你有两种解决方案:

框架 内部的可可足类动物

两种解决方案都将为您提供完全封装的模块,您可以在其中定义 API,通过 public 关键字在项目中可用。 在您的核心项目中,所有其他内容都将不可见。

管理您的项目将花费您更多的时间,但如果您使用 SOLID 原则编写此代码,您可能会获得更多可重用的代码,并且这些框架可以仅使用 import 定义导入到其他项目中。

【讨论】:

以上是关于将 Swift 应用程序的组件划分为 Swift 模块的主要内容,如果未能解决你的问题,请参考以下文章

将viewController添加为子视图Swift不显示任何组件

与金属 swift 并行计算数组值的总和

如何在 UIPickerview iOS swift 中为组件赋予标题

Swift:由字符串分隔的组件

如何在 ios swift 中使用故事板平均划分按钮图像?

如何使用 CIFilter 在 Swift 中将 UIImage 转换为灰度?