[SwiftPM] Swift Package Manager にリソースを追加してプロジェクトから使うまでのステップを説明
Sponsor Link
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 で、同一ファイルからのみ使用できるという定義です。
class ClassA {
public fileprivate(set) var propValue:Int = 0
}
struct initializer
class を使用していると気づきにくいですが、struct を使用する時は、default initializer や memberwise initializer がよく使用されます。
明示的に定義しなくて良いので非常に便利なのですが、デフォルトのアクセス制御は、internal, fileprivate, private のいずれかです。
(private のプロパティがあると private となり、filepriavate のプロパティがあれば、file private、そうでなければ、internal となります。)
いずれも、外部モジュールからはアクセスできないものです。
この暗黙に定義される initializer を public や open にするためには、自分でそれらを再定義しなければいけません。
少し手間なのですが、このことは、言語仕様にも明記されています。
public struct SwiftIntroView : View {
@Binding var present:Bool
public let introPages: SwiftIntroPages
public init(isPresented: Binding, _ introPages: SwiftIntroPages) { // - 新たに public として定義
self._present = isPresented
self.introPages = introPages
}
...
まとめ: SwiftPackage 化するときに気をつける点
- class / struct のアクセス制御に気をつける
- プロパティのアクセス制御に気をつける
- struct の default initializer や memberwise initializer に気をつける
説明は以上です。
不明な点やおかしな点ありましたら、ご連絡いただけるとありがたいです。
Sponsor Link