【Swift】FileManagerでファイルを保存!操作方法や格納場所
この記事からわかること
- SwiftのFileManagerとは?
- 使い方や設定方法、メリット
- iOSのファイルシステム:サンドボックス構造とは?
- 格納できるディレクトリの種類
- ディレクトリ(フォルダ)を作成する方法
index
[open]
\ アプリをリリースしました /
SwiftでファイルをiOSデバイス内に保存する方法をまとめていきたいと思います。
iOSアプリで端末(ローカル)にデータを永続的に保存する方法
Swiftではアプリ内からデータを永続的に保存する手段がいくつか存在します。
- テキストファイル
- UserDefaults
- Realm Swift(ライブラリ)
- Keychain
それぞれに一長一短がありますが、今回はFileManagerを使用した方法をまとめていきます。
Swiftでファイルを保存する際のポイント
Swiftでファイルを保存、読み込み、書き込みなどを行う際のポイントをまずは確認してみます。
ポイント
- サンドボックス構造
- Documentsディレクトリ
- URL型
- FileManager
アプリ内で生成したファイルなどを保存するにはiOSのファイルシステム構造やディレクトリの役割、FileManagerクラスの使い方が重要になってきます。
iOSのファイルシステム:サンドボックス構造
iOSのファイルシステムはサンドボックス構造が採用されています。サンドボックス構造とはサンドボックス(砂場)と呼ばれる外部とは隔離された仮想領域を用意し、その中でのみ動作や操作を許容する構造です。これにより外部の重要なプログラムなどへ悪意あるアクセスや動作が及ばないようにすることができます。
インストールしたiOSアプリはサンドボックス内に格納され動作しています。保存されたデータなどもサンドボックス内に格納され、アンインストール時に保存されたデータなども一緒に削除されます。
iOSアプリでファイルを保存する場合もサンドボックス内の決められたディレクトリ内に保存していきます。
おすすめ記事:【Swift】ファイルアプリからDocumentsフォルダへアクセス許可する方法!
参照できるディレクトリ
ファイルの保存先として使用できるのは下記のような構造になっているディレクトリ群のようです。それぞれに役割が決まっており、適切な場所へのファイルの格納が大事になってきます。Appleが定めているガイドラインに反したファイル管理をしているとアプリの審査がリジェクト(却下)されてしまうこともあるようです。
参考文献:FileSystem Programming Guide
Documents
ユーザーが生成したファイルや画像や動画などのデータなど、ユーザーが閲覧するファイルを保存します。このディレクトリ内はiTunes/iCloudにバックアップされます。
Library
Documentフォルダに格納するデータ以外を保存するためのディレクトリです。ディレクトリの内容はLibrary/Cachesサブディレクトリ以外は、iTunesとiCloudによってバックアップされます。
tmp
テンポラリファイル(temporary files:一時的に作成されるファイル)が保存されるディレクトリです。tmp内のファイルは不要になったら削除することが推奨されています。またアプリが起動していないタイミングで自動で削除される可能性もあります。このフォルダはiTunes/iCloudにバックアップされません。
AppDataディレクトリを確認する方法
実際にAppDataディレクトリを確認するには少し手順があります。下記の記事を参考にしてください。
おすすめ記事:AppDataディレクトリを確認する方法
FileManagerクラスの使い方
FileManagerとはファイルやディレクトリに関する操作(パスの取得や作成、削除、コピーなど)を行うことのできるクラスです。このクラスを使用することでローカルへのパス取得や、ファイルの保存や書き込み、ファイルの容量や更新日時の取得が可能になります。
FileManagerオブジェクトにはdefaultプロパティを介してアクセスします。
サンドボックス内のディレクトリパスを取得する
各ディレクトリのパスを取得するにはurlsメソッドを使用します。引数for:に取得したいパスの値を引数in:には対象のアプリフォルダドメインを指し示す.userDomainMaskを指定します。返り値はオプショナル型の配列なのでfirstで最初の要素を取得し、!でアンラップすることでURL型のパスが取得できます。
Documentsディレクトリのパス
Libraryディレクトリのパス
Library/cacheディレクトリのパス
tmpディレクトリのパス
Homeディレクトリのパスと応用
NSHomeDirectory()を使って構築したディレクトリへのパスはString型ですが、FileManagerを使って取得したパスはURL型になります。
取得できるパスが異なることがあるので注意
例えばDocumentsディレクトリのパスを取得すると以下のようなApplication/UUID形式で取得することができます。このUUID部分はアプリをアップデートしたりすると変わることがあるのでこのパスをそのままローカルに保存して使用しても取得できなくなることがあるので注意してください。
URL構造体とは?
Swiftで定義されているURL構造体はURLを扱うための構造体です。例えばString型をURL型にキャスト(型変換)したい場合はURL(string:)形式のイニシャライザを使用することで変換できます。
URLで囲うとオプショナルバリューになるので!を使って強制的にアンラップしておきます。
ファイルの書き込み処理
引数に受け取ったテキストをDocumentsディレクトリ内の「sample.txt」に書き込み処理を行うwritingFile関数を定義してみます。
FileManagerはまずdefaultでFileManagerオブジェクトを生成できます。さらにurlsで引数for:に指定したパスを取得することができます。以下のようにコードを分割しても同意です。urlsで帰ってくるのはオプショナルバリューとなったURL型なのでアンラップしないといけない点に注意してください。
おすすめ記事:Optional(オプショナル)型とnilとは?
appendingPathComponentはURLに追記処理ができます。これでDocuments/sample.txtまでのフルパスが完成します。writeで引数toに指定したパスに書き込み処理を行えます。該当ファイルが存在しない場合は自動で生成して書き込み処理を行います。atomicallyは書き込み中にエラーが発生してもファイルが壊れないように一時的なファイルを作成してくれます。
おすすめ記事:【Swift/String】write(to:atomically:encoding:)メソッドでファイルに文字列を書き込む方法!
おすすめ記事:【Swift】do-catchとthrows文の使い方!エラーハンドリングのやり方
ファイルの読み込み処理
Documentsディレクトリ内の「sample.txt」を読み込み内容を戻り値として返すreadingFile関数を定義してみます。
ファイルの読み込み処理はString型にキャストできるString()で行うことができます。内部のイニシャライザーが引数contentsOf: URLに指定されているURLのデータを取得し文字列として返してくれます。
ファイルの削除処理
Documentsディレクトリ内の「sample.txt」を削除するremoveFile関数を定義してみます。削除処理はfileManager.removeItemで実行できるのでfileManagerにFileManagerオブジェクトを格納して呼び出しやすくしておきます。
ファイルのコピー処理
Documentsディレクトリ内の「sample.txt」をコピーするcopyFile関数を定義してみます。コピー処理はfileManager.copyItemで実行できます。引数にコピー元とコピー先のURL型のパスを渡すだけです。
空のファイルの作成処理
指定したパスに空のファイルを作成するならcreateFileメソッドを使用します。引数atPathにはString型でファイルパスを渡します。contentsにはnilを渡せば空のファイルが、何かしらのデータを渡せば書き込まれた状態のファイルが生成されます。
ファイルが存在するかどうか
指定したファイルパスにファイルがあるかどうかを識別するにはfileExistsメソッドを使用します。引数atPathにはString型でファイルパスを渡します。存在すればtrueを返します。
先ほどの空のファイル作成処理ではファイルが既に存在する場合は作成処理を行わないようにしています。
エラーの意味
ディレクトリ(フォルダ)の作成
ディレクトリを作成するにはappendingPathComponentメソッドを使用して、引数conformingToに.directoryを渡せばOKです。
私がSwift UI学習に使用した参考書
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。






