Swift PMを使い倒す話をしたところ、モジュールとフレームワークってどう違うのか?という質問をいただいたので回答してみたいと思います。

https://youtu.be/0DeC672gFto?t=2688

Swiftのドキュメントにはアクセスレベルの観点でこのように記載されています。

Modules and Source Files Swift’s access control model is based on the concept of modules and source files. A module is a single unit of code distribution—a framework or application that’s built and shipped as a single unit and that can be imported by another module with Swift’s importkeyword. Each build target (such as an app bundle or framework) in Xcode is treated as a separate module in Swift. If you group together aspects of your app’s code as a stand-alone framework—perhaps to encapsulate and reuse that code across multiple applications—then everything you define within that framework will be part of a separate module when it’s imported and used within an app, or when it’s used within another framework. A source file is a single Swift source code file within a module (in effect, a single file within an app or framework). Although it’s common to define individual types in separate source files, a single source file can contain definitions for multiple types, functions, and so on.

これを読んでなんのこっちゃという方が本稿の対象なので、もう少し噛み砕いて説明します。

Q. Moduleとは

A. ライブラリから提供されるAPIを記したものです

大雑把にimportができるものという認識を持っていればよさそうです。

importさえできれば、その形式はFrameworkやAppでも大丈夫です。

<aside> 💡 Applicationもimportできるのか?と思った方はTest targetで @testable import Appと書いて、Applicationのソースコードにアクセスしていることを思い出しましょう。

</aside>

モジュールをimportすると、publicやopenといったAccess Modifierがついた変数やメソッドをimportしたモジュールで利用することができます。

XcodeやSwift PMにおけるモジュールの扱われ方

Xcodeではそれぞれのビルドターゲットがモジュールとして扱われます。モジュールがビルドターゲットであるということは、それぞれのモジュールでバラバラにビルドされるということです(もちろん依存関係は考慮しながら)。

Swift PMにおいては、targetsに記述するものがモジュールです。

targetを書くことによって、他のモジュールでimportが可能になります。

この状態で、⌘ + sを押してセーブすると、次のように.swiftmoduleというディレクトリが生成されます。