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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34558968/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 08:22:38  来源:igfitidea点击:

Dividing a Swift application's components into Swift modules

xcodeswiftmvvmmodule

提问by Christopher Simmons

I'm writing an iOS application in Swift, and I'm trying to figure out how to organize the project into separate modules. I'm using an MVVM architecture, and I want to make the Model, ViewModel, and View components separate Swift modules that make only subsets of themselves accessible to the modules that import them. The files in the View would import the ViewModel, and files in the ViewModel would import the Model. How can I accomplish this? Note that I'm not trying to create libraries that multiple applications can share. I'm just trying to enforce separation of components using modules.

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

EDIT: Maybe the question is, "What mechanism should I use to create modules aside from the one that comes with the initial iOS application project?"

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

One of the answers in "How do you use Namespaces in Swift?" https://stackoverflow.com/a/24032860/215400says, "classes (etc) are implicitly scoped by the module (Xcode target) they are in." From that, one might conclude that targets correspond to modules and that the answer is to create separate targets within an Xcode project, but I tried that earlier, and tskulbru is saying that I need multiple Xcode projects.

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

Regarding multiple Xcode projects, the File > New > Project > iOS Framework & Library > Cocoa Touch Framework option didn't look right because it's supposed to be for things that use UIKit, and two of the modules I want to create shouldn't depend on UIKit. The other "Framework & Library" option, Cocoa Touch static library, isn't an option with Swift.

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

Another StackOverflow post mentioned using private Pods. After spending an hour working on that, I concluded that it wasn't the right solution because I shouldn't have to edit these modules in different workspaces.

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

采纳答案by tskulbru

This isn't possible without creating separate projects for the modules you want to create. This is because the way Swift handles namespacing.

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

Eonil answered this better than me: https://stackoverflow.com/a/24032860/215400(Copy below)

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

Answered by SevenTenElevenin the Apple dev forum:

SevenTenElevenApple 开发论坛中的回答:

Namespaces are not per-file; they're per-target (based on the "Product Module Name" build setting). So you'd end up with something like this:

import FrameworkA
import FrameworkB

FrameworkA.foo()

All Swift declarations are considered to be part of some module, so even when you say "NSLog" (yes, it still exists) you're getting what Swift thinks of as "Foundation.NSLog".

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

import FrameworkA
import FrameworkB

FrameworkA.foo()

所有 Swift 声明都被认为是某个模块的一部分,因此即使您说“NSLog”(是的,它仍然存在),您也会得到 Swift 认为的“Foundation.NSLog”。

Also Chris Lattnertweeted about namespacing.

此外克里斯·拉特纳啾啾关于命名空间

Namespacing is implicit in swift, all classes (etc) are implicitly scoped by the module (Xcode target) they are in. no class prefixes needed

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

回答by user3292998

From my perspective if you want to encapsulate your components, probably you have two solutions:

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

  • Framework
  • Internal cocoapods
  • 框架
  • 内部可可豆

Both solutions will give you fully encapsulated modules, where you can define API that will be available in project through publickeyword. All other things will be not visible in your core project.

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

Managing your project will cost you a lot more time, but if you write this using SOLID principles, probably you will get more reusable code and those frameworks could be imported to other project just using importdefinition.

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