アプリケーションのドキュメントディレクトリは、セッション間で保持され、バックアップから復元される必要があるユーザーファイルの永続ストレージです。Apple File System Programming Guide, 2026によると、iOSではDocumentsディレクトリはキャッシュや一時ディレクトリとは異なり、iCloudバックアップに自動的に含まれます。ドキュメントディレクトリを適切に使用することで、アプリのアップデートや再インストール時にユーザーファイルが失われないことが保証されます。
重要なポイント
context.filesDirで、手動バックアップ管理が必要ドキュメントディレクトリは、アプリケーションのサンドボックス内にある専用ストレージで、ユーザーファイルを永続的に保存するために設計されています。キャッシュとは異なり、このディレクトリ内のファイルはユーザーにとって重要とみなされ、容量が不足してもシステムによって削除されず、アプリのアップデート時も保持され、デバイスの同期時にバックアップされます。iOSでは、DocumentsディレクトリはSandboxコンテナの一部であり、iCloudバックアップに自動的に含まれます。Androidには直接の同等物はなく、同等のものはcontext.filesDirで、これも永続ファイルを対象としていますが、組み込みのバックアップ機構はありません。
Androidにおけるドキュメントディレクトリと内部ストレージの違いは最小限です。両方ともアプリのサンドボックスにあり、アンインストール時に削除され、他のアプリからはアクセスできません。主な違いは意味的なものです。Documents Directoryはファイルがユーザーによって作成またはインポートされたことを前提とするのに対し、内部ストレージにはアプリの内部ファイル(データベース、設定)が含まれる可能性があります。iOSでは違いがより顕著です。Documentsは自動的にバックアップされますが、Library/Application Supportはバックアップされません。これはストレージ戦略に影響します。Documentsにはユーザーが新しいデバイスで復元したいものだけを配置し、Application Supportにはアプリが再作成できる内部データを配置します。
サンドボックスアーキテクチャにより、他のアプリケーションがあなたのアプリのドキュメントディレクトリにアクセスできないことが保証されます。iOSでは、ジェイルブレイクなしに他のアプリのDocumentsにアクセスすることは不可能です。Androidでは、ルートアクセスにより任意のアプリのfilesDirを読み取れるため、機密データ(トークン、暗号化キー)はEncryptedSharedPreferencesやAndroidX SecurityライブラリのEncryptedFileを使用して追加で保護する必要があります。
ドキュメントディレクトリには、ユーザーにとって価値があり、アプリの再起動後やデバイス復元後もアクセス可能であるべきデータを保存する必要があります。すべてのファイルがこのディレクトリへの保存に適しているわけではありません。選択はデータの種類と使用シナリオによって異なります。
ユーザーファイルはドキュメントディレクトリの主要なコンテンツです。エディタで作成されたテキストドキュメント、アプリのカメラで撮影した画像、エクスポートされたPDFレポート、オーディオ録音、メモなどが該当します。これらの各ファイルはユーザー自身またはそのリクエストによって作成され、常にアクセス可能でなければなりません。iOSでは、DocumentsのファイルはシステムのFilesアプリに表示され、ユーザーは標準のファイルマネージャーを通じて管理できます。Androidには同様の表示はなく、アプリ自体が保存されたファイルを表示するためのインターフェースを提供する必要があります。
SQLiteデータベースと設定ファイルは通常、ドキュメントディレクトリの近くに保存されますが、その中には保存されません。iOSでは、データベースはLibrary/Application Supportに配置されます。Filesアプリに表示されるべきではなく、別途バックアップされるべきではないからです。Androidでは、データベースはデフォルトで/data/data/<package>/databases/にRoomまたはSQLiteOpenHelperを介して作成されます。データベースにユーザーコンテンツ(メモ、日記、財務記録)が含まれている場合は、システムバックアップを確保するためにfilesDirに配置できます。Roomでは、RoomDatabase.Builderコールバックを介してデータベースストレージ用のカスタムディレクトリを指定できます。
val dbFile = File(context.filesDir, "user_database.db")
val db = Room.databaseBuilder<AppDatabase>(
context,
dbFile.absolutePath
).build()
ユーザーが他のアプリからインポートしたファイルや、あなたのアプリからエクスポートしたファイルも、ドキュメントディレクトリに保存する必要があります。iOSでは、UIDocumentPickerViewControllerを介したインポートは、asCopy: trueパラメータを使用すると自動的にファイルのコピーをDocumentsに配置します。Androidでは、SAFダイアログを介したインポートもアプリのサンドボックスにファイルのコピーを作成します。データをエクスポートする場合(連絡先を含むCSVファイルの作成など)、最初にファイルをDocuments/filesDirに保存し、その後Share Sheetを介してユーザーに共有オプションを提供します。これにより、ユーザーが送信後にファイルを保存し忘れても、後で使用するためにアプリ内にコピーが残ることが保証されます。
Androidでは、ドキュメントディレクトリの機能はcontext.filesDirが担います。さらに、SDカード上にcontext.externalFilesDirディレクトリも利用可能ですが、データの整合性は保証されません。これらのディレクトリを操作する主要なテクニックを見ていきましょう。
filesDirはAndroidにおけるアプリの永続ファイル用のメインディレクトリです。アプリのサンドボックス内にあり、アンインストール時に完全に削除されます。Fileインスタンスを取得するには、context.filesDirを使用します。これは/data/data/<package>/files/へのパスを返します。ファイルを作成および読み取るには、標準のJava/Kotlin File操作、またはファイル名を受け取りFileInputStream/FileOutputStreamを返すContextメソッドopenFileInput()とopenFileOutput()を使用します。openFileOutput()メソッドは、ファイルがまだ存在しない場合は自動的にfilesDirに作成し、アクセスモードを指定できます:MODE_PRIVATE(現在のアプリのみ)、MODE_APPEND(追記)、またはMODE_WORLD_READABLE(非推奨、API 24+から未使用)。
val fileName = "report.pdf"
val content = "PDF content".toByteArray()
context.openFileOutput(fileName, Context.MODE_PRIVATE).use { stream ->
stream.write(content)
}
val bytes = context.openFileInput(fileName).use { stream ->
stream.readBytes()
}
Android 10+では、Scoped StorageモデルはfilesDirに影響しません。アプリ自身のサンドボックスへの完全なアクセスは維持されます。filesDir内のすべての読み取りおよび書き込み操作には追加の権限は必要ありません。ただし、filesDirを介して他のアプリのファイルにアクセスしようとすると、例外が発生します。ファイルを共有するには、FileProviderを使用します。FileProviderは、ファイルを別のアプリに転送するための一時的なcontent URIを作成します。FileProviderはAndroidManifest.xmlで<provider>タグを介して宣言され、XMLパスファイルで設定されます。これはアプリ間でファイルを転送するための標準的なメカニズムであり、例えばACTION_SENDを使用したIntentで画像を送信する際に使用されます。
iOSでは、Documents Directoryは特別なステータスを持つアプリのSandboxコンテナの一部です。このディレクトリのファイルは自動的にiCloudバックアップに含まれ、Filesアプリに表示され、App Storeを介したアプリのアップデート時も保持されます。
Documentsの自動バックアップはiOSの重要な利点です。ユーザーがデバイスをiTunesに接続するかiCloud Backupを有効にすると、Documents/内のすべてのファイルがバックアップにコピーされます。新しいデバイスで復元する際、ユーザーは追加の操作なしですべてのファイルを取得できます。ただし、アプリがDocumentsに大量のデータを保存している場合、この利点は欠点になります。バックアップ時間が増加し、iCloudストレージがすぐに不足する可能性があります。したがって、Documentsには復元時にユーザーが本当に必要とするファイルのみを保存する必要があります。一時ファイル、キャッシュ、再作成可能なデータは、CachesまたはLibrary/Application Supportに配置する必要があります。Appleは、isExcludedFromBackup属性を使用して、インターネットから再ダウンロード可能なファイルをバックアップから除外することを推奨しています。
let fm = FileManager.default
let docsURL = fm.urls(
for: .documentDirectory,
in: .userDomainMask
).first!
let fileURL = docsURL.appendingPathComponent("notes.txt")
let text = "ノートの内容"
try text.write(to: fileURL, atomically: true, encoding: .utf8)
iCloud Driveを使用すると、ユーザーのデバイス間でDocumentsのファイルを同期できます。同期を有効にするには、アプリはNSDocumentまたはUIDocument APIを使用する必要があります。これらはバージョン管理と競合解決を自動的に管理します。別のアプローチとして、CloudKitとともにiCloudを使用する方法もあります。これにより同期のより柔軟な制御が可能になりますが、CloudKit Dashboardでの設定が必要です。iCloud Driveを使用する際は、編集の競合(マージまたは最終書き込み優先)を正しく処理し、アプリのインターフェースを介してユーザーに同期ステータスを通知するようにしてください。iCloudは即時同期を保証しません。遅延はファイルサイズと接続品質に応じて、数秒から数分の範囲になります。重要なデータについては、トランザクション書き込みとバージョン管理を使用して、競合が発生した場合にファイルの以前のバージョンを復元できるようにします。
正しい選択をDocuments DirectoryとCache Directoryの間で行うことが、ユーザーデータストレージの信頼性を決定します。選択を誤ると、データ損失(重要なファイルがキャッシュに保存されている場合)またはバックアップのオーバーフロー(一時ファイルがDocumentsに保存されている場合)のいずれかにつながります。
| 基準 | Documents Directory | Cache Directory |
|---|---|---|
| データ整合性の保証 | 高 — システムによって削除されない | 低 — 消去される可能性あり |
| バックアップ(iOS) | 自動的にiCloudへ | バックアップされない |
| ユーザーの可視性(iOS) | Filesアプリ内 | 非表示 |
| アップデート時の消去 | 消去されない | 消去される可能性あり |
| 推奨サイズ | 任意だが設定で制御 | 最大100~200 MB |
| データタイプ | ユーザーファイル | 一時的な再作成可能データ |
ベストプラクティスとして、ドキュメントディレクトリの使用にはいくつかの重要なルールがあります。第一に、このディレクトリからファイルを削除する前に常にユーザーの確認を求めてください。キャッシュとは異なり、ドキュメントを削除するとユーザーコンテンツが不可逆的に失われる可能性があります。第二に、ファイルのバージョン管理を実装してください。既存のファイルを上書きする際は、_backupサフィックスを付けて前のバージョンを保存するか、スナップショットメカニズムを使用します。第三に、ユーザーにドキュメントディレクトリからファイルを表示、名前変更、削除、エクスポートするためのインターフェースを提供します。iOSでは、Documentsのファイルは自動的にFilesに表示されます。Androidでは、独自のファイルマネージャーを実装するか、サードパーティのライブラリを使用する必要があります。
アプリのアップデート時のデータ移行には特に注意してください。新しいバージョンがファイルストレージ構造を変更する場合(例えば、データをあるサブディレクトリから別のディレクトリに移動したり、ファイル形式を変更したりする場合)、アップデート後の最初の起動時に1回限りの移行を実装してください。データスキーマのバージョン番号をSharedPreferencesに保存し、一致しない場合に移行を実行します。移行が完了する前に古いファイルを削除しないでください。障害が発生した場合でも、ユーザーがデータを失わないようにする必要があります。移行に形式変換が含まれる場合(JSONからSQLiteへの切り替えなど)、元のファイルを移行日付とともに別のディレクトリにバックアップとして保存します。Apple Human Interface Guidelinesの推奨に従い、ユーザーはアップデート後30日以内にアプリの設定を通じて変更を元に戻せる必要があります。
よくある質問
DocumentsはFilesアプリに表示され、自動的にiCloudにバックアップされます。Application SupportはFilesに表示されず、デフォルトではバックアップされません。ユーザーに表示する必要のないアプリの内部データにはApplication Supportを選択してください。
はい、アカウントを削除する際は、そのアカウントに関連するすべてのローカルファイルをクリアするオプションをユーザーに提供してください。「すべてのローカルデータを削除しますか?」と尋ねるダイアログを表示し、どのファイルが影響を受けるかをリストアップします。これはGDPRの要件であり、App StoreとGoogle Playのポリシーへの準拠です。
iOSでは、iCloudまたはiTunesのバックアップからデバイスを復元するだけで、Documentsのファイルは自動的に復元されます。Androidでは、Google Drive Backup APIを使用してfilesDirからファイルをバックアップするか、クラウドサービスを介したエクスポートを実装します。
iOSでは、ユーザーはFilesアプリを通じてファイルを削除できます。Androidでは、削除はアプリのインターフェースを通じてのみ可能です。誤ったデータ損失を防ぐために、削除後30日以内に復元可能なドキュメントゴミ箱を実装することをお勧めします。
追加の操作は必要ありません。iOSとAndroidは、App StoreまたはGoogle Playを介したアップデート時にドキュメントディレクトリを自動的に保持します。ただし、ストレージ構造を変更する場合は、設定でスキーマバージョン番号を確認して、新しいバージョンの最初の起動時にデータ移行を実装してください。
まとめ
context.filesDirを使用する — ファイルはアップデート時に保持されるが、組み込みのバックアップ機構はないターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。