ファイルシステムの基礎

ファイルシステムは、データファイルとアプリケーションの永続ストレージ、およびオペレーティングシステム自体に関連するファイルを処理します。したがって、ファイルシステムはすべてのプロセスで使用される基本リソースのひとつと言えます。

APFSは、macOS、iOS、watchOS、およびtvOSのデフォルトファイルシステムです。iOS 10.3以降およびmacOS High Sierra以降では、HFS+に代わってAPFSがデフォルトのファイルシステムです。macOSは、さらに、「サポートされるファイルシステム」で説明しているその他のさまざまなフォーマットをサポートしています。

基盤となっているフォーマットにかかわらず、デバイスに接続されているすべてのディスクは、物理接続とネットワーク経由の間接接続のどちらであっても、ファイルの単一の集合を形成するための領域を生み出します。ファイルの数はすぐに数百万規模に増加するため、ファイルシステムはディレクトリを使って階層的な組織を編成します。iOSとmacOSの基本的なディレクトリ構造は似ていますが、各システムでアプリケーションとユーザーデータが組織化される方式が異なります。

ファイルシステムと相互作用するコードの作成を開始する前に、まずファイルシステムの編成の概要と、作成するコードに適用されるルールを理解する必要があります。適切なセキュリティ権限を持たないディレクトリへのファイルの書き込みを禁止する基本原則以外に、アプリケーションは正しく振る舞い、適切な場所にファイルを配置することが期待されます。ファイルを保存する正確な場所はプラットフォームに依存しますが、全般的な目標として、ユーザーのファイルが常に検出しやすい状態に維持され、コードで使用されるファイルがシステム内のユーザーのアクセスできない場所に保管される必要があります。

iOSのファイルシステムについて

iOSのファイルシステムは、単独で実行されるアプリケーションに合わせて調整されています。システムの簡潔さを維持するために、iOSデバイスのユーザーはファイルシステムに直接アクセスできず、アプリケーションもこの規則に従うことが要求されます。

iOS標準ディレクトリ:ファイルの保存場所

セキュリティ上の観点から、iOSアプリケーションのファイルシステムとの相互作用は、アプリケーションのサンドボックスディレクトリ内部のディレクトリでのみ発生します。新しいアプリケーションのインストール中、インストーラは、アプリケーション用のコンテナディレクトリをサンドボックスディレクトリに多数作成します。コンテナディレクトリにはそれぞれ役割があります。バンドルコンテナディレクトリはアプリケーションのバンドルを保持し、データコンテナディレクトリはアプリケーションやユーザーが用いるデータを保持します。データコンテナディレクトリはいくつものサブディレクトリに分かれており、これを利用してデータを分類、整理できます。さらに、実行時にiCloudコンテナなど別のコンテナディレクトリにアクセスすることもあります。

これらのコンテナディレクトリは、ファイルシステムにおいてはアプリケーションのプライマリビューと呼ばれます。図1-1に、アプリケーションのサンドボックスディレクトリを図示しています。

図1-1  iOSアプリケーションが専用のサンドボックスディレクトリ内で動作する様子

アプリケーションは、一般にコンテナディレクトリ外のファイルへのアクセス、またはそのようなファイルの作成が禁止されます。このルールの例外は、アプリケーションがパブリックシステムインターフェイスを使用して、ユーザーの連絡先や音楽などのコンテンツにアクセスする場合です。そのような場合、システムのフレームワークはヘルパクラスを使い、適切なデータストアからの読み取りやデータストアの修正に必要な、ファイルに関連したすべての操作をハンドルします。

表1-1に、サンドボックスディレクトリ内の重要なサブディレクトリの一部を示し、それぞれの用途を説明しています。またこの表には、各サブディレクトリの追加的なアクセス制限が記述され、ディレクトリの内容がiTunesとiCloudによってバックアップされるかどうかが示されています。

表1-1  iOSアプリケーションの共通に使用されるディレクトリ

ディレクトリ

説明

AppName.app

アプリケーションのバンドル。このディレクトリ内に、アプリケーション本体とそのリソースがすべて収容されています。

ここにファイルを書き出すことはできません。改竄を防止するため、バンドルディレクトリはインストール時に署名されます。このディレクトリに書き込みをすると署名が変化するため、アプリケーションは起動できなくなります。ただし、ここに保存されているリソースに、読み込み専用でアクセスすることは可能です。詳しくは、『Resource Programming Guide』を参照してください。

iTunesまたはiCloudはこのディレクトリの内容をバックアップしません。ただし、App Storeから購入したアプリケーションの最初の同期は、iTunesが実行します。

Documents/

ユーザーが生成したデータを保存するために使います。ファイル共有の機能により、ユーザーはこのディレクトリ以下にアクセスできます。したがって、ユーザーに見せても構わないファイルのみ置いてください。

iTunesおよびiCloudはこのディレクトリの内容をバックアップします。

Documents/Inbox

このディレクトリは、外部エンティティからアプリケーションに対して要求されたファイルのアクセスに使用します。特に、「メール(Mail)」プログラムは、アプリケーションに関連した電子メール添付ファイルをこのディレクトリに保存します。Document Interaction Controllersもファイルを同じディレクトリに配置する場合があります。

アプリケーションはこのディレクトリのファイルの読み取りと削除が可能ですが、新しいファイルの作成または既存のファイルへの書き込みは実行できません。ユーザーがこのディレクトリのファイルの編集を試みた場合、アプリケーションが暗黙的にディレクトリからファイルを移動しなければ変更を行うことができません。

iTunesおよびiCloudはこのディレクトリの内容をバックアップします。

Library/

これは、ユーザーのデータファイル以外のファイル用の最上位ディレクトリです。通常、標準的なサブディレクトリを用意し、いずれか適当な場所に保存します。iOSアプリケーションは通常、Application SupportおよびCachesというサブディレクトリを使いますが、独自のサブディレクトリを作成しても構いません。

ユーザーに見せたくないファイルはLibraryサブディレクトリ以下に置いてください。ユーザーデータのファイル保存用に使ってはなりません。

Libraryディレクトリの内容はiTunesおよびiCloudによってバックアップされます(ただし、Cachesサブディレクトリは除く)。

Libraryディレクトリおよびよく使われるサブディレクトリについて詳しくは、「Libraryディレクトリはアプリケーション固有のファイルを保存」を参照してください。

tmp/

このディレクトリは、アプリケーションを次に起動するまで保持する必要のない一時ファイルを書き込むために使用します。不要になったファイルは削除しなければなりません。もっとも、アプリケーションが動作していないときに、システムがこのディレクトリ以下をすべて消去することがあります。

iTunesまたはiCloudはこのディレクトリの内容をバックアップしません。

iOSアプリケーションは、DocumentsLibrarytmpなどの下に、追加のディレクトリを作成できます。これを利用してファイルを整理するとよいでしょう。

上記のiOSアプリケーションのディレクトリの参照方法について詳しくは、「標準ディレクトリのアイテムの検索」を参照してください。ファイルの置き場所に関して、「アプリケーションファイルの置き場所」にいくつかヒントを載せてあります。

アプリケーションファイルの置き場所

iOSデバイスの同期やバックアップに長期間かからないよう、ファイルの置き場所は慎重に選択しなければなりません。大容量のファイルを扱うアプリケーションの場合、iTunesやiCloudへのバックアップには相応の時間がかかります。もちろんストレージ容量を圧迫することにもなるので、積極的に削除して空き容量を増やす、あるいはiCloudへのバックアップを無効にする、という手段をユーザーは考えてしまうでしょう。このことを念頭に、アプリケーションデータの保存に関しては、次のガイドラインに従って実装してください。

  • ユーザーデータはDocuments/以下に置いてください。これは一般に、ユーザーに積極的に見せるファイルです。ユーザーが自由に作成、インポート、削除、編集する対象です。たとえば描画アプリケーションの場合、ユーザーが作成するグラフィックファイルがこれに当たります。テキストエディタであればテキストファイルが該当します。動画/音声アプリケーションの場合、ユーザーが後で試聴するためにダウンロードしたファイルもこれに当たります。

  • アプリケーションが生成する補助ファイルは、Library/Application support/ディレクトリ以下に置きます。一般にこのディレクトリには、アプリケーションが処理に用いる、ユーザーには見せないでおきたいファイルを収容します。アプリケーションバンドルから取り出したデータファイル、設定ファイル、テンプレート、リソースの修正版なども、ここに置くとよいでしょう。

  • Documents/およびApplication Support/以下のファイルは、自動的にバックアップの対象になります。NSURLIsExcludedFromBackupKeyキーを指定して-[NSURL setResourceValue:forKey:error:]を実行することにより、バックアップ対象から除外できます。いつでも再生成またはダウンロードできるファイルは、この対象から外してください。大容量のメディアファイルの場合、これは特に重要です。ダウンロードした動画や音声は、バックアップ対象に含めないようにしてください。

  • 一時データはtmp/ディレクトリに置いてください。一時データとは、長期間にわたって保存しておく必要がないデータのことです。使い終わったら削除して、デバイス上の空間を消費し続けないようにしなければなりません。システムは、アプリケーションが動作していない間、定期的にここにあるファイルを消去します。したがって、一度停止した後、ファイルが残っていることを前提として処理してはなりません。

  • データキャッシュファイルはLibrary/Caches/ディレクトリ以下に置きます。キャッシュデータは、一時データよりは長期間にわたって残しておきたいけれども、補助ファイルほどではない場合に有用です。一般にキャッシュデータは、なくてもアプリケーションの動作に影響しませんが、性能改善の効果が期待できます。例として、データベースのキャッシュファイルや、一時的でいつでもダウンロード可能なデータなどがあります。なお、ディスク空間を確保するため、システムがCaches/ディレクトリを消去することがあるので、必要ならばいつでも生成し直し、あるいはダウンロードできるようになっていなければなりません。

macOSのファイルシステムについて

macOSのファイルシステムは、ユーザーとソフトウェアがいずれもファイルシステムにアクセスする、Macコンピュータ向けに設計されています。ユーザーはFinderから直接ファイルシステムにアクセスします。Finderは一部のファイルとディレクトリを非表示あるいは別名で表示し、ファイルシステムをユーザー指向のビュー形式で示します。アプリケーションは、ディスクに表示されるときの完全なファイルシステムを示すシステムインターフェイスを使用して、ファイルシステムにアクセスします。

ファイルの配置はドメインに依存

macOSでは、ファイルシステムは複数のドメインに分割されます。ドメイン内ではそれぞれの用途に基づいて、ファイルとリソースが分類されます。この分類により、ユーザーはファイルの特定のサブセットにのみ配慮すればよいため、ファイル操作が簡潔になります。またファイルのドメイン別の配列により、ドメイン内のファイルへの一括アクセス権が適用され、不正なユーザーによる意図的あるいは不注意なファイルの変更を防ぐことができます。

  • ユーザードメインは、システムにログインしたユーザーに固有のリソースを含みます。このドメインは理論的にはすべてのユーザーを対象としますが、実行時のユーザーのホームディレクトリのみを反映します。ユーザーのホームディレクトリは、コンピュータのブートボリューム(/Usersディレクトリ)またはネットワークボリューム上に置くことができます。各ユーザーは(権限に関係なく)、各自のホームディレクトリにアクセスし、同ディレクトリを制御することができます。

  • ローカルドメインは、現在のコンピュータのローカルアプリケーションなどのリソース、および現在のコンピュータの全ユーザー間で共有されるリソースを含みます。ローカルドメインは、単一の物理ディレクトリに対応しませんが、ローカルのブート(およびルート)ボリュームの複数のディレクトリから構成されます。このドメインは通常はシステムにより管理されますが、管理権限を持つユーザーもこのドメインのアイテムの追加、削除、または修正が可能です。

  • ネットワークドメインは、ローカルエリアネットワーク(LAN)の全ユーザー間で共有される、アプリケーションとドキュメントなどのリソースを含みます。このドメインのアイテムは、通常はネットワークファイルサーバ上に配置され、ネットワーク管理者の管理下に置かれます。

  • システムドメインは、Appleでインストールされるシステムソフトウェアを含みます。システムドメインのリソースは、システムの実行時に要求されます。ユーザーはこのドメインのアイテムの追加、削除、または変更が禁止されています。

図 1-2は、macOSインストールのローカルファイルシステムへの、Local、System、Userの各ドメインのマッピングプロセスを示しています(ネットワークドメインは示されていませんが、多くの点でローカルドメインに類似しています)。この図には、ユーザーに表示されるディレクトリが示されています。ユーザーのシステムに応じて、ほかのディレクトリが表示される場合や、図に示されたディレクトリが表示されない場合があります。

図1-2 ローカルmacOSファイルシステム

macOSのディレクトリの内容について詳しくは、「macOS標準ディレクトリ:ファイルの保存場所」を参照してください。macOSで通常はユーザーに表示されないディレクトリ(およびその理由)について詳しくは、「非表示ファイルとディレクトリ:ユーザー体験の簡素化」を参照してください。

macOS標準ディレクトリ:ファイルの保存場所

システム供給かアプリケーションで生成されるかを問わず、すべてのファイルにmacOS内の場所が割り当てられます。表1-2は、macOSインストールの最上位ディレクトリの一部と、各ディレクトリに含まれるコンテンツタイプの一覧です。

表1-2 macOSで一般的に使用されるディレクトリ

ディレクトリ

用途

/Applications

このディレクトリに、コンピュータの全ユーザーに使用されるアプリケーションをインストールします。App Storeは、ユーザーが購入したアプリケーションを自動的にこのディレクトリにインストールします。

Utilitiesサブディレクトリは、ローカルシステムの管理に使用されるアプリケーションのサブセットを含みます。

このディレクトリは、ローカルドメインに含まれます。

ライブラリ

システムには複数のLibraryディレクトリが存在し、それぞれが異なるドメインまたは特定のユーザーに関連付けられています。アプリケーションは、アプリケーション固有(またはシステム固有)のリソースの保存にLibraryディレクトリを使用します。

このディレクトリの内容、およびこのディレクトリを使用してアプリケーションをサポートする方法について詳しくは、「Libraryディレクトリはアプリケーション固有のファイルを保存」を参照してください。

/Network

このディレクトリは、ローカルエリアネットワーク(LAN)のコンピュータのリストを含みます。

ネットワークファイルサーバ上のファイルのパスは、/Networkディレクトリで始まるとは限りません。パス名は、ネットワークのマウント量など複数の要因に応じて変わります。たとえば、ユーザーがConnect to Serverコマンドを使用してボリュームをマウントする場合、パスは/Volumesディレクトリから開始します。コードを記述する場合、ブートボリューム以外のすべてのボリュームのファイルを、ネットワークベースのサーバ上に配置できると仮定してください。

/System

このディレクトリは、macOSの実行に必要なシステムリソースを含みます。これらのリソースはAppleにより供給され、変更できません。

このディレクトリには、システムドメインの内容が含まれます。

/Users

このディレクトリは、1つまたは複数のユーザーホームディレクトリを含みます。ユーザーホームディレクトリは、ユーザー関連のファイルが保存される場所です。通常のユーザーのホームディレクトリには、以下のサブディレクトリが含まれます。

  • Applications — ユーザー固有のアプリケーションを含みます。

  • Desktop — ユーザーのデスクトップのアイテムを含みます。

  • Documents — ユーザーのドキュメントとファイルを含みます。

  • Downloads — インターネットからダウンロードされたファイルを含みます。

  • Library — ユーザー固有のアプリケーションファイルを含みます(macOS 10.7以降では非表示)。

  • Movies — ユーザーのビデオファイルを含みます。

  • Music — ユーザーの音楽ファイルを含みます。

  • Pictures — ユーザーの写真を含みます。

  • Public — ユーザーが共有を予定しているコンテンツを含みます。

  • Sites — ユーザーの個人サイトで使用されるウェブページを含みます(これらのページを表示する場合、Web共有を有効にする必要があります)。

上記のディレクトリは、ユーザーのドキュメントとメディアの保存専用に使用されます。アプリケーションは、ユーザーにより明示的に指示されている場合を除き、上記のディレクトリにファイルを書き込むことができません。このルールの唯一の例外はLibraryディレクトリです。このディレクトリは、現在のユーザーのサポートに必要なデータファイルの保存にアプリケーションで使用される場合があります。

サブディレクトリの中でPublicディレクトリのみが、システムのほかのユーザーからアクセスできます。ほかのディレクトリへのアクセスは、デフォルトで制限されます。

表 1-2のディレクトリは、macOSユーザーに表示されるディレクトリですが、ファイルシステムに存在するディレクトリはこれだけではありません。ユーザーによる不要なファイルアクセスを防ぐため、macOSでは多くのディレクトリが非表示になっています。

サンドボックス内のmacOSアプリケーションファイルのコンテナ

サンドボックス内のmacOSアプリケーションは、それぞれのApplication SupportCache、一時ディレクトリ、その他の関連ドキュメントをすべて、システム定義のパス(NSHomeDirectory関数で取得可)で示されるディレクトリ内に保存します。

詳しくは、『App Sandbox Design Guide』を参照してください。

非表示ファイルとディレクトリ:ユーザー体験の簡素化

ユーザー体験を簡素化するために、Finderとユーザーが使用する一部の特定のインターフェイス(OpenパネルとSaveパネルなど)は、ユーザーが使用する必要のない多くのファイルとディレクトリを非表示にしています。非表示アイテムの多くは、ユーザーが直接アクセスできない(あるいはアクセスすべきではない)システム固有またはアプリケーション固有のリソースです。表示されないファイルとディレクトリには以下のようなものがあります。

  • Dotディレクトリとファイル。名前がピリオド(.)文字で始まるファイルまたはディレクトリは、自動的に非表示になります。これはUNIXの規約に基づき、システムスクリプトとその他の特殊なタイプのファイルとディレクトリの非表示に使用されていました。このカテゴリの2つの特別なディレクトリは、それぞれ現在のディレクトリと親ディレクトリを参照する、...ディレクトリです。

  • UNIX固有のディレクトリ。このカテゴリのディレクトリは、従来のUNIXのインストールから継承されています。システムのBSDレイヤの重要な部分ですが、エンドユーザー以上にソフトウェアデベロッパにとって有用です。非表示の重要なディレクトリの一部を以下に示します。

    • /bin — 必須のコマンドラインバイナリを含みます。通常は、これらのバイナリはコマンドラインスクリプトから実行します。

    • /dev — 接続されたハードウェアのマウント箇所など、必須デバイスファイルを含みます。

    • /etc — ホスト固有の設定ファイルを含みます。

    • /sbin — 必須のシステムバイナリを含みます。

    • /tmp — アプリケーションとシステムで生成された一時ファイルを含みます。

    • /usr — 必須ではないコマンドラインバイナリ、ライブラリ、ヘッダファイル、その他のデータを含みます。

    • /var — ログファイルと、その他のさまざまな内容のファイルを含みます(ログファイルは通常は、コンソールアプリケーションで表示されます)。

  • 明示的に非表示にされたファイルとディレクトリ。Finderはユーザーが直接アクセスできない特定のファイルまたはディレクトリを、非表示にする場合があります。このもっとも特筆すべき例として/Volumesディレクトリがあり、ここにはコマンドラインからローカルファイルシステムにマウントされた、各ディスクのサブディレクトリが含まれます(Finderはローカルディスクのアクセス用に、別のユーザーインターフェイスを提供しています)。macOS 10.7以降では、Finderは~/Libraryディレクトリ、すなわちユーザーのホームディレクトリ内のLibraryディレクトリも非表示にします。

  • パッケージとバンドル。パッケージとバンドルは、Finderがファイルと同様にユーザーに提示するディレクトリです。バンドルはアプリケーションなどの実行可能ファイルの内部作業を隠し、ファイルシステムの外部での移動が可能な単一のエンティティのみを表示します。同様に、パッケージにより個別の複数のファイルから構成される複雑なドキュメント形式の実装がアプリケーションで可能になり、同時に、ユーザーに対して表面上は単一ドキュメントに見られる内容を表示し続けることができます。

Finderとその他のシステムインターフェイスは、ファイルとディレクトリをユーザーに非表示にしますが、NSFileManagerなどのCocoaインターフェイスは、通常はユーザーに表示されないファイルまたはディレクトリをフィルタリングしません。このため、これらのインターフェイスを使用するコードは、理論的には、ファイルシステムとその内容を完全に収めたビューを保持しています(実際には、プロセスがアクセスするのは、適切な権限を持つファイルとディレクトリに限定されます)。

ファイルとディレクトリに代替名を割り当てられる

状況によっては、Finderはファイルシステム内の実際の名称と一致しないファイル名またはディレクトリ名をユーザーに提示します。これらの名前は表示名として知られ、ファイルとディレクトリの情報をユーザーに提示するために、Finderと特定のシステムコンポーネント(OpenパネルとSaveパネルなど)によってのみ使用されます。表示名は内容をより分かりやすくユーザーに示すため、ユーザー体験の向上が図られます。たとえば、macOSは以下のような状況で表示名を使用します。

  • ローカライズ名。ApplicationsLibraryMusicMoviesなどの多くのシステムディレクトリに対して、ローカライズ名が提供されます。アプリケーションも同様に、アプリケーション自体およびアプリケーションで作成されたディレクトリにローカライズ名を割り当てます。

  • ファイル名拡張子の非表示。デフォルトで、すべてのファイルのファイル名拡張子は非表示です。ユーザーはオプションを変更できますが、ファイル名拡張子の非表示が有効な場合、ファイル名の最後のピリオドの後の文字(およびピリオド)は表示されません。

表示名は、ファイルシステム内のファイルの実際の名称を反映しません。プログラムによりファイルまたはディレクトリにアクセスするコードは、ファイルシステムのインターフェイスを使用してアイテムを開いたり操作するときの、アイテムの実際の名前を指定する必要があります。アプリケーションで表示名が使用されるのは、ファイルまたはディレクトリの名前をユーザーに表示する場合に限定されます。NSFileManagerdisplayNameAtPath:メソッドを使うと、任意のファイルまたはディレクトリの表示名を取得できます。

アプリケーションで生成されるディレクトリのローカライズ方法について詳しくは、『File System Advanced Programming Topics』を参照してください。アプリケーションの内容のローカライズについて詳しくは、『インターナショナライゼーションとローカリゼーションのガイド』を参照してください。

Libraryディレクトリはアプリケーション固有のファイルを保存

Libraryディレクトリは、アプリケーションとその他のコードモジュールがカスタムデータファイルを保存する場所です。iOSとmacOSのいずれのコードを記述する場合でも、Libraryディレクトリの構造を理解することは重要です。このディレクトリは、データファイル、キャッシュ、リソース、環境設定、また特定の状況ではユーザーデータの保存にも使用します。

システム全体に複数のLibraryディレクトリがありますが、コードからアクセスが必要になるのは一部に過ぎません。

  • 現在のホームディレクトリのLibrary — ユーザー固有のすべてのファイルが格納されるため、ディレクトリのもっとも多く利用されるバージョンです。iOSの場合、Libraryはアプリケーションデータバンドル内にあります。macOSでは、アプリケーションのサンドボックスディレクトリ、または(アプリケーションがサンドボックス内にインストールされていない場合は)現在のユーザーのホームディレクトリです。

  • /Library(macOSのみ) — ユーザー間でリソースを共有するアプリケーションは、リソースをこのバージョンのLibraryディレクトリに保存します。サンドボックス内のアプリケーションは、このディレクトリの使用が許可されていません。

  • /System/Library(macOSのみ) — このディレクトリはAppleで予約されています。

使用するLibraryディレクトリのバージョンを選択した後、ファイルを保存する場所を確認する必要があります。Libraryディレクトリ自体には、アプリケーション固有の内容がいくつかの一般的なカテゴリに細分化される、複数のサブディレクトリが含まれます。表1-3に、最もよく使われるサブディレクトリをリストアップしています。macOSのLibraryディレクトリには、リスト内に示されていない多くのサブディレクトリが含まれますが、ほとんどは用途がシステムに限定されます。サブディレクトリの詳細なリストについては、「Libraryディレクトリの詳細」を参照してください。

表1-3  Libraryディレクトリの主要なサブディレクトリ

ディレクトリ

用途

Application Support

このディレクトリは、ユーザーのドキュメントに関連付けられていないアプリケーションデータファイルを保存する場合に使用します。たとえば、アプリケーションで生成されたデータファイル、設定ファイル、テンプレート、その他のアプリケーションで管理される固定リソースまたは修正可能なリソースの保存にこのディレクトリを使用できます。アプリケーションも、アプリケーションのバンドルに元々格納されていたリソースの修正可能なコピーを保存する場合に、このディレクトリを使用する場合があります。ゲームでは、ユーザーが購入した新しいレベル、またサーバからダウンロードされた新しいレベルの保存にこのディレクトリが使用されます。

このディレクトリのすべての内容は、アプリケーションのバンドルIDまたは社名を名前に使った、カスタムサブディレクトリに置かれます。

iOSでは、iTunesおよびiCloudはこのディレクトリの内容をバックアップします。

Caches

このディレクトリは、アプリケーションが簡単に作成し直すことが可能な、アプリケーション固有のサポートファイルの記述に使用します。一般的にアプリケーションはこのディレクトリの内容の管理、および必要に応じたファイルの追加と削除に責任を持ちます。

iOS 2.2以降では、このディレクトリの内容がiTunesまたはiCloudによってバックアップされません。また、システムはデバイスの完全な復元の間に、このディレクトリのファイルを削除します。

iOS 5.0以降では、稀ですが、システムのディスクスペースが非常に少ない場合に、Cachesディレクトリが削除される場合があります。このような削除は、アプリケーションの実行中は起こりません。ただし、Cachesディレクトリが消去される状況は、バックアップからの復元時に限らないことを覚えておいてください。

Frameworks

macOSでは、複数のアプリケーションで共有されるフレームワークは、ローカルまたはユーザードメインのいずれかにインストールできます。システムドメインのFrameworksディレクトリは、macOSアプリケーションの作成時に使用するフレームワークを保存します。

iOSでは、アプリケーションはカスタムフレームワークをインストールできません。

Preferences

このディレクトリには、アプリケーション固有の環境設定ファイルを保存します。ディレクトリ内に、デベロッパ自身がファイルを作成してはいけません。デベロッパのファイルには、NSUserDefaultsクラスまたはCFPreferences APIを使用して、アプリケーションの環境設定の値を取得し設定します。

iOSでは、iTunesおよびiCloudはこのディレクトリの内容をバックアップします。

iCloudファイルのストレージコンテナ

iCloudは、iCloudを利用するアプリケーションのファイルを保存するための構造化されたシステムを提供します。

ユーザーがアプリケーションのユーザーインターフェイスで作成し、表示するドキュメント(たとえば、Pages、Numbers、Keynoteから開いたり、保存したりするドキュメント)は、Documentsディレクトリに保存されます。保存済みのゲームもDocumentsディレクトリに保存されるファイルの例です。ゲームの保存時にも、アプリケーションからある種の選択方法が提供される可能性があるためです。

アプリケーションで、ユーザーによる直接の表示または修正を禁止するものは、Documentsディレクトリの外部に配置する必要があります。アプリケーションはコンテナディレクトリ内部にサブディレクトリを作成できるため、必要に応じて、プライベートファイルを配列できます。

アプリケーションは、ローカルのファイルとディレクトリを作成するのとまったく同じ方法で、iCloudコンテナディレクトリにファイルとディレクトリを作成します。またすべてのファイルの属性が保存され、ファイルに拡張属性が追加されると、それらの属性はiCloudとユーザーのほかのデバイスにもコピーされます。

またiCloudコンテナでは、ドキュメント形式を作成せずに簡単にアクセスできるキー値ペアを保存できます。

ファイルの内容のタイプの識別方法

ファイルの内容のタイプは、主に2種類の方法で識別します。

Uniform Type Identifier(UTI)は、「タイプ」を持つと見なされたエンティティのクラスを一意に識別する文字列です。UTIはすべてのアプリケーションとサービスが認識し、信頼できる、一貫性のあるIDをデータに割り当てます。またUTIはほかの方法よりも柔軟性があります。これはファイルとディレクトリ以外に、データのタイプの表現にも使用できるためです。UTIの一例を示します。

UTIベースのインターフェイスがファイルタイプの指定に使用できる場合、必ずそのインターフェイスを優先的に使用してください。多くのmacOSインターフェイスでは、作業の必要なファイルまたはディレクトリに対応したUTIを指定できます。たとえば、OpenパネルでファイルフィルタとしてUTIを使用し、ユーザーが選択できるファイルのタイプをアプリケーションの処理が可能なタイプに制限できます。NSDocumentNSPasteboardNSImageを含む複数のAppKitクラスがUTIをサポートしています。iOSでは、UTIはペーストボードのタイプの指定にのみ使用されます。

特定のファイルのUTIを判断する方法の1つに、ファイル名拡張子の確認があります。ファイル名拡張子は、ファイルの末尾に付加される文字列で、ピリオドでファイル主部から分離されます。固有の文字列はそれぞれ、特定のタイプのファイルを識別します。たとえば、.strings拡張子はローカライズ可能な文字列データのリソースファイルを識別しますが、.png拡張子は、移植可能なネットワークグラフィック形式の画像データのファイルを識別します。

アプリケーションでカスタムファイル形式が定義されている場合、それらの形式と関連するファイル名拡張子をアプリケーションのInfo.plistファイルに登録する必要があります。CFBundleDocumentTypesキーは、アプリケーションで認識され、開くことができるファイル形式を指定します。カスタムファイル形式のエントリには、ファイル名拡張子、さらにファイルの内容に対応したUTIを含める必要があります。その情報に基づいて、該当するタイプのファイルがアプリケーションにダイレクトされます。

UTIおよびその使い方について詳しくは、『Uniform Type Identifiers Overview』を参照してください。CFBundleDocumentTypesキーについて詳しくは、『Information Property List Key Reference』を参照してください。

セキュリティ:作成するファイルの保護

すべてのユーザーデータとシステムコードはディスクのどこかに保存されるため、ファイルの整合性とファイルシステムの保護は重要な作業です。そのような理由により、内容の保護、および内容の盗難やほかのプロセスによる破損の防止には複数の方法が使用されます。

ファイルの作業時のセキュアなコーディング方式について詳しくは、『セキュアコーディングガイド』を参照してください。

サンドボックスは被害の拡大を制限

iOSとmacOS 10.7以降では、サンドボックスによって、アプリケーションによるファイルシステムの禁止箇所への書き込みが回避されます。サンドボックスを使う各アプリケーションには、書き込み可能なコンテナがいくつかあります。アプリケーションはほかのアプリケーションのコンテナ、またはサンドボックスの外部のほとんどのディレクトリに書き込むことができません。これらの制約により、アプリケーションのセキュリティ違反が起きたときの、潜在的な被害が制限されます。

macOS 10.7以降のアプリケーションを作成するデベロッパは、セキュリティを強化するために、作業中のアプリケーションをサンドボックスに保存することが奨励されます。iOSアプリケーションのデベロッパは、iOSのインストール時にシステムで自動的に設定されるため、アプリケーションを明示的にサンドボックスに保存する必要はありません。

サンドボックスと、ファイルシステムのアクセスに対する制約のタイプについて詳しくは、『Mac App Programming Guide』と『App Sandbox Design Guide』を参照してください。

すべてのファイルアクセスに適用される許可とアクセス制御リスト

ファイルとディレクトリへのアクセスは、アクセス制御リスト(ACL)とBSD許可の組み合わせにより管理されます。アクセス制御リストは、ファイルまたはディレクトリに対して実行可能な内容と不可能な内容、および実行者を正確に定義する、きめの細かい制御リストです。アクセス制御リストに基づき、特定のファイルまたはディレクトリへの異なるレベルのアクセス権を、個々のユーザーに付与することができます。これに対して、BSD許可はファイルの所有者、指定した特定のユーザーグループ、全ユーザーの3つのユーザークラスにのみアクセスを許可できます。詳しくは、『セキュリティの概要』を参照してください。

iOSアプリケーションは必ずサンドボックスで実行されるため、各アプリケーションで生成されたファイルに特定のACLと許可が割り当てられます。ただし、macOSアプリケーションは、Idntity Serviceを使用して、アクセスするファイルのアクセス制御リストを管理できます。Identity Services(およびCollaborationフレームワーク)の使い方について詳しくは、『Identity Services Programming Guide』を参照してください。

ディスクでのファイルの暗号化

macOSとiOSはいずれも、ディスクでのファイルの暗号化をサポートしています。

  • iOS。iOSアプリケーションは、ディスクでの暗号化が必要なファイルを指定できます。ユーザーが暗号化されたファイルを含むデバイスのロックを解除すると、アプリケーションの暗号化されたファイルへのアクセスを許可する復号キーが生成されます。ユーザーがデバイスをロックすると、復号キーが破壊され、ファイルへの不正なアクセスが禁止されます。

  • macOS。ユーザーはディスクユーティリティアプリケーションを使用して、ボリュームの内容を暗号化できます(またシステム環境設定Security & Privacyから、ブートボリュームを暗号化することもできます)。暗号化されたディスクの内容をアプリケーションが利用できるのは、コンピュータの稼働時に限られます。ユーザーがコンピュータをスリープに移行する、またはシャットダウンすると、復号キーが破壊され、ディスクの内容への不正なアクセスが回避されます。

iOSでは、ディスクベースの暗号化を利用するアプリケーションは、ユーザーがデバイスをロックした場合、暗号化されたファイルの利用を停止する必要があります。デバイスのロックにより復号キーが破壊されるため、暗号化されたファイルへのアクセスはデバイスのアンロック時に制限されます。デバイスがロックされている間にiOSアプリケーションをバックグラウンドで実行できる場合、暗号化されたファイルにアクセスせずにこの実行が可能でなければなりません。macOSの暗号化されたディスクは、コンピュータの稼働中は常にアクセスできるため、macOSアプリケーションはディスクレベルの暗号化の処理のために、特別な操作を行う必要がありません。

iOSで暗号化されたファイルを扱う方法について詳しくは、『iOSアプリケーション:プログラミングガイド』を参照してください。

同期によりファイル関連のコードの強度を保証

ファイルシステムは、サードパーティ製アプリケーションとシステムアプリケーションで共有されるリソースです。複数のアプリケーションが同時にファイルとディレクトリにアクセスできるため、特定のアプリケーションの変更により、別のアプリケーションに古いファイルシステムが表示される可能性が生じます。別のアプリケーションでこのような変更の処理に対応できない場合、未知の状態あるいはクラッシュに陥る可能性があります。アプリケーションが特定のファイルの存在に依存している場合、そのようなファイルの変更の通知に同期化インターフェイスを使用できます。

ファイルシステムの同期は、主にmacOSで問題になります。macOSでは、ユーザーがFinderや任意の数のほかのアプリケーションを同時に直接操作できるためです。ただし、macOSでは同期の問題に対処する以下のインターフェイスが提供されます。

ファイル、並列処理、スレッドの安全性

ファイル関連の操作にはハードディスクとの相互作用が伴い、ほかの大半の操作よりも速度が遅くなるため、iOSとmacOSのファイル関連の大半のインターフェイスは並列処理を前提に設計されています。設計に非同期操作を組み込む技術もありますが、ほとんどの技術はディスパッチキューまたは二次スレッドから安全に操作を実行できます。表1-4に、本書で説明する主要な技術の一部と、特定のスレッドまたは任意のスレッドから使う場合の安全性を一覧にしています。インターフェイスの機能について詳しくは、そのインターフェイスのリファレンスドキュメントを参照してください。

表1-4  主要なクラスと技術のスレッドの安全性

クラス/技術

メモ

NSFileManager

ほとんどの作業においては、デフォルトのNSFileManagerオブジェクトを複数のバックグラウンドスレッドから同時に使用しても安全です。この規則の唯一の例外として、ファイルマネージャのデリゲートと相互作用する作業があげられます。ファイルマネージャオブジェクトをデリゲートで使用する場合、NSFileManagerクラスの一意のインスタンスを作成し、そのインスタンスをデリゲートで使用することが推奨されます。この一意のインスタンスは、1度に1つのスレッドから使用します。

Grand Central Dispatch

GCD自体はどのスレッドから使用しても安全です。ただし、ブロックをスレッドが安全な方法で記述する責任は作者の側にあります。

NSFileHandleNSData、Cocoaストリーム

ファイルデータの読み書きに使用するFoundationオブジェクトの大半は、任意のシングルスレッドから使用できますが、複数のスレッドから同時に使用することはできません。

OpenパネルとSaveパネル

OpenパネルとSaveパネルはユーザーインターフェイスの一部であるため、両パネルは必ずアプリケーションのメインスレッドから提示し、操作する必要があります。

POSIXルーチン

ファイルを操作するためのPOSIXルーチンは、一般に、任意のスレッドから安全に操作できるように設計されています。詳しくは、対応するmanページを参照してください。

NSURLおよびNSString

パスの指定に使用するイミュータブルなオブジェクトは、任意のスレッドから安全に使用できます。このオブジェクトはイミュータブルであるため、複数のスレッドから同時に参照できます。当然ですが、これらのオブジェクトのミュータブルなバージョンは、1度に1つのスレッドからのみ使用します。

NSEnumeratorとそのサブクラス

Enumeratorオブジェクトは、任意のシングルスレッドから安全に使用できますが、複数のスレッドから同時に使用できません。

ファイルの操作にスレッドセーフなインターフェイスを使用する場合においても、複数のスレッドまたは複数のプロセスで同じファイルの操作を試みると問題が生じます。複数のクライアントが同時に同じファイルを修正するのを禁止するセーフガードはとられていますが、そのようなセーフガードによりファイルへの排他的なアクセスが常に保証されるとは限りません(ほかのプロセスによる共有ファイルへのアクセスを禁止することもできません)。共有ファイルへの変更をコードに確実に認識させるためには、ファイルコーディネータを使用して、そのようなファイルへのアクセスを管理します。ファイルコーディネータについて詳しくは、「ファイルコーディネータとプレゼンタの役割」を参照してください。