CleanArchitecuture を導入しており、Infra や Domain などの層を Embedded Framework を使って分けていました。
その際、Infra でテキストファイルを開こうとしたらエラーになり、「あぁバンドルバンドル…」と思いつつ、どうやったっけ??ってなるので、自分用も兼ねて対処方法を載せます。
-
開発環境(前提条件)
-
そもそも Bundle とは
-
問題となるのは
-
解決方法
-
さいごに
開発環境(前提条件)
・Xcode14.0(2022年10月24日再確認済み)
・Swift5
・プロジェクト内で Embedded Framework を利用している
そもそも Bundle とは
ディスク上のバンドルディレクトリに格納されているコードとリソースを表現したものです。
Xcode でいうと
TARGET → Build Phases → Copy Bundle Resources
に含まれているもので、普通に開発してたら Storyboard や Assets 等もここに追加されていきます。
これらのファイルはお馴染みの Bundle.main でアクセスできます。
細かい説明は本題から外れるので、詳細が気になる方は
公式ドキュメント
をご覧ください。
問題となるのは
データ関連は全て Infra から取得したかったので、テキストファイルもそこに置きました。
それを文字列にして取得したんですが、無意識に Bundle.main と書いてました。
guard let url = Bundle.main.url(forResource: "filename", withExtension: "txt") else {
fatalError("テキストファイルないやんけ")
let text = try String(contentsOfFile: url.path,
encoding: .utf8)
// ...テキトーな処理
} catch {
print(error.localizedDescription)
guard
let
url
=
Bundle
.
main
.
url
(
forResource
:
"filename"
,
withExtension
:
"txt"
)
else
{
fatalError
(
"テキストファイルないやんけ"
)
}
do
{
let
text
=
try
String
(
contentsOfFile
:
url
.
path
,
encoding
:
.
utf8
)
// ...テキトーな処理
}
catch
{
print
(
error
.
localizedDescription
)
}
これ FatalError になります。
Bundle.main のディレクトリは以下のようになります。
/private/var/containers/Bundle/Application/********-****-****-****-************/Sample.app
そして、Embedded Framework で Infra を追加した場合のディレクトリは、Sample.app の直下に
/Frameworks/Infra.framework
というような構成で追加されます。
そのため、Infra にファイルを追加したとしても、Bundle.main とはパスが違うってわけです。
僕は Infra の中で Bundle.main のようにアクセスしたかったので、以下のようにエクステンションを追加しました。
static var current: Bundle {
class DummyClass {}
return Bundle(for: type(of: DummyClass()))
// 使う時は Bundle.current でアクセスできます。
東京で6年ほど iOSアプリの開発をして、今は実家に戻って介護&リモートで開発しています o(・_・)9
個人的なアプリ開発ではライトアプリを3つほど。
スマホ、ガジェット大好き ٩( ‘ω’ )و
UI/UXのデザイン系も興味あるマン。