[SwiftPM] Package 化するときに忘れがちなポイント

SwiftPackageManagerEyeCatch

自作ライブラリを SwiftPM でパッケージ化するときに、気をつける点を説明します。
SwiftPackageManagerEyeCatch[SwiftPM] Swift Package Manager にリソースを追加してプロジェクトから使うまでのステップを説明

SwiftPM 化することによる変化点

Swift でのアクセス定義は、デフォルトでは 同一モジュール内でのアクセス となっています。

ですので、1つのプロジェクト内で アプリケーションコード と ライブラリコード が混在している時は特に気にしなくても動作します。

SwiftPM でのパッケージ化は、別モジュールにすることですので、モジュールを超えるアクセスを考慮して指定することが必要となります。

実際に気をつける点

ライブラリとしての設計に関わる点も多いですが、Swift Package 化にあたり、以下の点をクリアにする必要があります。

class / struct アクセス制御

SwiftPM 化するということは、class / struct を外部から使用することを意味します。

定義した class や struct は、デフォルトでは internal という同一モジュールからのみのアクセスが許される定義となっていますので、変更が必要となります。

外部モジュールからもアクセスできるような宣言は、open と public があり、以下のような違いがあります。

open
外部モジュールから、サブクラスの作成や上書き定義も自由に行うことができる
public
外部モジュールから、使用することができる。ただし、サブクラス作成や上書き定義は、同一モジュールからのみ可能

open と public のどちらにするかは、ケースバイケースです。また、外部から直接使用する必要のないクラスは、そのまま(internal) にしておく方が良いです。

プロパティアクセス

プロパティに対しても、アクセス制御を考える必要があります。デフォルトでは、internal です。

プロパティの場合は、setter に対して異なるアクセス制御を設定することもできますので、さらに考えることが増えます。

例えば、以下は、プロパティ propValue に対して、get は public で外部モジュールからアクセスできるが、set は、fileprivate で、同一ファイルからのみ使用できるという定義です。

アクセス制御例

struct initializer

class を使用していると気づきにくいですが、struct を使用する時は、default initializer や memberwise initializer がよく使用されます。

明示的に定義しなくて良いので非常に便利なのですが、デフォルトのアクセス制御は、internal, fileprivate, private のいずれかです。
(private のプロパティがあると private となり、filepriavate のプロパティがあれば、file private、そうでなければ、internal となります。)

いずれも、外部モジュールからはアクセスできないものです。

この暗黙に定義される initializer を public や open にするためには、自分でそれらを再定義しなければいけません。

少し手間なのですが、このことは、言語仕様にも明記されています。

struct の initializer を public として定義例

まとめ: SwiftPackage 化するときに気をつける点

SwiftPackage 化するときに気をつける点
  • class / struct のアクセス制御に気をつける
  • プロパティのアクセス制御に気をつける
  • struct の default initializer や memberwise initializer に気をつける

説明は以上です。
不明な点やおかしな点ありましたら、ご連絡いただけるとありがたいです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です