XcodeGenでは指定しなければ基本、ディレクトリはすべて自動でグループとして扱われる。
そのためフォルダ参照したい場合は、フォルダ参照するパスのタイプを指定する必要がある。
ここまでは公式仕様にも書かれているのでわかる。
が、さらに罠があったので共有したい。
わかりやすいように以下にサンプルプロジェクトを配置したので、これを使って説明していきたい。
https://github.com/yumemi-ajike/FolderReferencesWithXcodeGen
- Xcode13.1
- XcodeGen2.25.0
グループとして参照
targets:
sources:
で指定した path
以下のディレクトリ群はグループとして扱われるため
targets:
FolderReferencesWithXcodeGen:
type: application
platform: iOS
sources:
- path: FolderReferencesWithXcodeGen
excludes:
- Info.plist
こうなるのがデフォルト仕様。
しかし、最終的には.appのリソースの中でImagesフォルダを持ちたいとすると、このままだとNG。
フォルダ参照
targets:
sources:
で指定したパスの type:
を folder
で指定する必要がある。
公式仕様にも明記されている。
targets:
FolderReferencesWithXcodeGen:
type: application
platform: iOS
sources:
- path: FolderReferencesWithXcodeGen
excludes:
- Info.plist
- path: FolderReferencesWithXcodeGen/Images # <-New
type: folder # <-New
これで一見よさそうだが、何故かグループとしても扱われてしまい、ProjectでもBuild Phase のCopy Bundle Resourcesでもフォルダ参照とグループ参照としての内部ファイル群の両方が追加される形となってしまう。。なんでやねん
Project | Build Phase のCopy Bundle Resources |
---|---|
フォルダ参照 + グループ参照を省く
targets:
sources:
で指定した path
で Images以下がグループ参照されてしまわないようにしたいので excludes
の指定にImagesを追加する。
targets:
FolderReferencesWithXcodeGen:
type: application
platform: iOS
sources:
- path: FolderReferencesWithXcodeGen
excludes:
- Info.plist
- Images # <-New
- path: FolderReferencesWithXcodeGen/Images
type: folder
Project | Build Phase のCopy Bundle Resources |
---|---|
これでグループ参照の重複が解消され、最終的に.appのリソースにはImagesフォルダ以下が入ることになる。
確認
アプリ起動時に.appのリソース内/Images/tree.jpgがあるか確かめる。
if let fileURL = Bundle.main.resourceURL?.appendingPathComponent("Images").appendingPathComponent("tree.jpg") {
print("filePath exists: \(FileManager.default.fileExists(atPath: fileURL.path))")
}
.appのリソース内/tree.jpgが無いか確かめる。
https://github.com/yumemi-ajike/FolderReferencesWithXcodeGen/blob/23f9c1a7a4145f156040661bbde9df08f0308e4d/FolderReferencesWithXcodeGen/AppDelegate.swift#L19-L21
if let fileURL = Bundle.main.resourceURL?.appendingPathComponent("tree.jpg") {
print("filePath exists: \(FileManager.default.fileExists(atPath: fileURL.path))")
}