Documents DirectoryはiOSアプリのサンドボックス内にあるディレクトリで、アプリセッション間で永続化され、iTunes File SharingおよびiCloudを介してユーザーがアクセスできるユーザーデータを保存するために設計されています。Apple File System Programming Guide(2024)によると、このディレクトリの内容は自動的にiCloudおよびiTunesのバックアップに含まれるため、開発者はDocumentsにどのデータを配置するかを意識的に選択する必要があります。Caches Directoryとは異なり、Documents内のファイルは容量不足時にシステムによって削除されません。サイズ管理の責任はアプリにあります。
重要なポイント
Documents DirectoryはiOSアプリのサンドボックス内にあるディレクトリで、起動間で永続化されユーザーがアクセスできるユーザーデータを保存するために設計されています。各アプリは独自の隔離されたサンドボックスを持ち、DocumentsはCaches、tmp、Libraryと並ぶ主要なディレクトリの1つです。
iOSは厳格なサンドボックスを採用しています。アプリは特別な許可なしに他のアプリのファイルシステムやシステムディレクトリにアクセスできません。Documents Directoryは、ユーザーがiTunes File Sharingを介して内容を表示できる唯一のディレクトリです(Info.plistでUIFileSharingEnabledキーが有効な場合)。
Apple WWDC 2023によると、App Storeの85%以上のアプリがDocuments Directoryを使用して少なくとも1種類のユーザーデータ(エクスポートされたPDF、保存されたゲームファイル、エクスポートされた画像など)を保存しています。
開発者が理解すべき重要な点:Documents内のファイルはiCloudおよびiTunesのバックアップに自動的に含まれます。アプリがDocumentsに大量の復元可能なデータ(画像キャッシュや一時ファイルなど)を保存すると、ユーザーのiCloudストレージ容量を不必要に消費することになります。
Swiftでは、Documents DirectoryへのパスはFileManagerを介して取得します。Appleは、最新のiOS機能との互換性を高めるために、文字列ベースではなくURLベースのAPIを使用することを推奨しています。
import Foundation
let fileManager = FileManager.default
guard let documentsURL = fileManager.urls(
for: .documentDirectory,
in: .userDomainMask
).first else { return }
// Documentsにファイルを作成
let fileURL = documentsURL.appendingPathComponent("report.pdf")
let data = Data("Hello, world!".utf8)
try data.write(to: fileURL)
Objective-CはNSSearchPathForDirectoriesInDomainsを使用します。これは、URLではなく文字列パスを返す、古いながらもサポートされているアプローチです。
@import Foundation;
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory,
NSUserDomainMask,
YES
);
NSString *documentsPath = paths.firstObject;
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"report.pdf"];
Swiftの最新プロジェクトではFileManager.urlsを使用する必要があります。このメソッドは文字列ではなくURLを返すため、パスエンコーディングエラーのリスクが低減され、コードの型安全性が向上します。
Documents Directoryは、ユーザーが作成したデータ、またはユーザーが明示的に必要とするデータを対象としています。Appleはこのディレクトリに適したいくつかのカテゴリを示しています。
ユーザーが作成またはインポートするファイル — テキストドキュメント、PDF、画像、エクスポートされたレポート、バックアップファイル。これらのデータはユーザーにとって直接的な価値があり、その損失は重大です。
ゲームのセーブ、アプリの状態ファイル、エクスポートされたプロジェクト — アプリの再インストール後にユーザーが復元を期待するすべてのものです。ただし、重要なデータについては、iCloud Key-Value StorageまたはiCloud同期を使用したCore Dataを追加で使用することをお勧めします。
| データタイプ | Documentsに適している | 代替 |
|---|---|---|
| PDFおよびテキストドキュメント | はい | — |
| 画像キャッシュ | いいえ | Caches Directory |
| ゲームのセーブ | はい | iCloud KVS |
| ログおよびデバッグデータ | いいえ | Cachesまたはtmp |
| エクスポートされたレポート | はい | — |
重要な基準:データをネットワークから再ダウンロードできるか再作成できる場合、その場所はCachesであり、Documentsではありません。Documentsの1ギガバイトは、ユーザーのiCloudバックアップの1ギガバイトです。
iOSは、デバイスがiTunesに接続されたとき、またはiCloudと同期するときに、Documents Directoryの内容を自動的にバックアップに含めます。この動作はディレクトリレベルでは無効にできません。NSURLIsExcludedFromBackupKey属性を使用してファイルごとにのみ設定できます。
iOS 5.0以降、AppleはDocumentsに大量の復元可能なデータを保存するアプリを拒否し始めました。Appleの推奨:再ダウンロード可能なファイルは、バックアップ除外フラグを付けてCaches Directoryに保存する必要があります。
import Foundation
let documentsURL = FileManager.default
.urls(for: .documentDirectory, in: .userDomainMask)
.first!
// ファイルをiCloudバックアップから除外
var resourceValues = URLResourceValues()
resourceValues.isExcludedFromBackup = true
var fileURL = documentsURL.appendingPathComponent("cached_data.json")
try fileURL.setResourceValues(resourceValues)
iCloudの同期は、アプリがiCloud Documentsを使用している場合、NSUbiquitousContainerを介して機能します。この場合、Documents Directoryのファイルはユーザーのデバイス間で自動的に同期されます。iCloudを使用しないアプリの場合、同期はバックアップに限定されます。
DocumentsとCachesの違いは、初心者のiOS開発者の間で最も一般的な誤解の1つです。主な違い:システムは空き容量を確保するためにいつでもCachesからファイルを削除できますが、ユーザーの知らないうちにDocumentsに触れることは決してありません。
| 特性 | Documents Directory | Caches Directory |
|---|---|---|
| iCloudバックアップ | あり(デフォルト) | なし |
| システムによる削除 | なし | 空き容量不足時 |
| iTunes File Sharing | あり(フラグ有効時) | なし |
| 目的 | ユーザーデータ | キャッシュ、一時データ |
| データ復元 | 復元が必要 | 再ダウンロード可能 |
Apple Developer Documentation(2024)によると、Documents Directoryの不適切な使用はレビュー時のアプリ拒否の一般的な理由の1つです。アプリがDocumentsに数メガバイトを超える復元可能なデータを保存している場合、AppleはCachesに移動するか、NSURLIsExcludedFromBackupKeyを適用することを推奨しています。
実用的なルール:ユーザーがファイルを失って悲しむならDocumentsに保存します。ファイルを再ダウンロードまたは再生成できるならCachesに保存します。
経験豊富なiOS開発者は、アプリのライフサイクルのすべての段階(開発からApp Store公開まで)でDocuments Directoryの問題を回避するのに役立ついくつかのルールを確立しています。
FileManager.enumerator(at:includingPropertiesForKeys:)を介してDocuments Directoryのサイズを定期的に確認します。ユーザーデータ以外でサイズが100 MBを超える場合、ストレージアーキテクチャを再検討する必要があります。
再ダウンロード可能なファイルには、isExcludedFromBackup = trueを設定します。これにより、ユーザーのiCloudストレージへの負荷が軽減され、App Reviewで拒否されるリスクが減少します。
Documentsのデータ形式を変更する場合は、移行を計画します。新しいファイルが正しく作成されたことを確認するまで、古いファイルを削除しないでください。バージョン固有のサブディレクトリを使用します。
import Foundation
let documentsURL = FileManager.default
.urls(for: .documentDirectory, in: .userDomainMask)
.first!
let versionDir = documentsURL.appendingPathComponent("v2")
try FileManager.default.createDirectory(
at: versionDir,
withIntermediateDirectories: true
)
これらのプラクティスに従うことで、ユーザーデータ損失のリスクを軽減し、iCloudバックアップサイズを削減し、App Storeレビューを簡素化できます。
よくある質問
はい、Files(iOS 11以降の標準アプリ)を介して可能です。Info.plistでUIFileSharingEnabledキーを有効にすると、Documents Directoryの内容がファイルアプリの「iPhone内」セクションに表示されます。ユーザーはファイルの表示、コピー、削除ができます。
アプリのサンドボックス全体(Documents Directory、Caches、tmp、Libraryを含む)がデバイスから完全に削除されます。iCloudのバックアップは、復元または手動削除まで保持されます。再インストール時に、アプリはクリーンなサンドボックスから開始します。
FileManager.enumeratorを使用してディレクトリ内のすべてのファイルを走査し、サイズを合計します。各ファイルについて、resourceValues(forKeys:)を介して.fileSize属性を取得します。代わりに、URLResourceKey.fileSizeKeyと.directoryEnumerationResultsを使用することもできます。
デフォルトでは、Core DataはSQLiteファイルをLibrary/Application Supportに作成し、Documentsには作成しません。データベースをDocumentsに移動することは推奨されません。iTunes File Sharingに含まれ、ユーザーが誤って削除または変更する可能性があります。例外は、アプリがCore Dataを介してユーザーに明示的にデータへのアクセスを提供する場合です。
UIFileSharingEnabled(Application supports iTunes file sharing)はInfo.plistのブール値キーです。YESに設定すると、ユーザーはiTunesおよびFilesを介してDocuments Directoryからファイルをコピーできます。Info.plistにキーを追加します:UIFileSharingEnabled = YES。アプリが実際にユーザードキュメントを作成する場合のみ有効にしてください。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。