【Swift】アプリ内のファイル読み書き

(2022/01/18 更新)

アプリ内のファイル読み書き方法を解説します。

スポンサーリンク

環境

この記事の情報は次のバージョンで動作確認しています。

【Xcode】12.4
【Swift】5.3.2
【iOS】14.4
【macOS】Big Sur バージョン 11.1
スポンサーリンク

iOSアプリのファイルシステム

iOSアプリは、システム(iOS)が不正に操作されるのを防ぐ為、アクセスできるフォルダがアプリ毎に隔離されています。(Sandbox構造)
対象のフォルダは、該当アプリからのみアクセスできますが、端末からアプリを削除すると一緒に削除されます。
本記事では、対象フォルダでのファイル読み書きについて解説します。

なお、アプリに元からバンドルされているリソースファイルにアクセスする方法は、【Swift】プロジェクト内のファイル読み込み を参照して下さい。

iOSアプリのフォルダ構成

こちらがiOSアプリから読み書きできるフォルダの構成例です。
(フォルダの開き方は、後で解説します)
iOSアプリのフォルダ構成

Documents
ユーザーが作成したファイル、あるいはアプリケーションで再作成できないドキュメントやその他データ(画像、動画など)のうち、ユーザーに見えるようにするファイルをここに保存します。
このフォルダの内容は、後述する方法によって「ファイル」アプリケーションで参照できます。
任意のサブフォルダを作成可能です。
このフォルダはiTunes/iCloudにバックアップされます。
上記に該当しないファイル(キャッシュデータなど)を置いた場合、AppStoreの審査でリジェクトになる場合があります。

Library
Documentフォルダに入れるようなデータ以外を保存するフォルダです。
UserDefaultsに保存したデータは、plistとしてこのフォルダ配下に保存されます。
このフォルダ配下に置いたファイルの内、Chacheフォルダ以外はiTunes/iCloudにバックアップされます。

Library/Application Support
アプリに必要であるが、アプリのデータベースファイルのようにユーザーに見えないようにするファイルをここに保存します。
Core DataのDBファイルもここに作成されます。
このフォルダはiTunes/iCloudにバックアップされます。

Library/Caches
再度ダウンロードまたは再生成できるデータを保存するフォルダです。
例として、データベースのキャッシュファイルや、雑誌、新聞、地図のアプリケーションで使用されるようなダウンロード可能なコンテンツなどが含まれます。
デバイスのディスクスペースが不足している場合、iOSはしばらく使用されていないアプリのキャッシュファイルを削除する可能性があります。
このフォルダはiTunes/iCloudにバックアップされません。

tmp
一時的にのみ使用されるデータを保存するフォルダです。
ファイルを使い終わったら削除をお勧めします。
アプリが起動していない時に、システムによって自動削除される可能性があります。
このフォルダはiTunes/iCloudにバックアップされません。

スポンサーリンク

アプリからファイルの読み書きをする

はじめにサンプルソースを示します。
「実行」ボタンを押すと、アプリケーションのDocumentsフォルダ内の"output.txt"ファイルに文字列を書き込みをし、その後同ファイルから内容を読み込むサンプルです。
実行ボタンはSwiftUIで実現していますが、ファイルの書き込みおよび読み込み処理にはSwiftUIの機能は使用していませんので、UIKitを使ったアプリでも流用可能です。

ファイル書き込み処理の解説

DocumentsフォルダURL取得

FileManager.default.urls()を使って、DocumentsフォルダURLを取得します。

引数(for)にはDocumentフォルダを示す.documentDirectoryを、引数(in)にはアプリのファイルが格納されているフォルダドメインを示す.userDomainMaskを指定します。
戻り値にはフォルダURLの配列が返るので、.firstをつけて先頭[0]の要素を取得します。

対象フォルダが取得できない場合はnilが戻りますので、その場合サンプルではfatalError()で強制的にアプリをクラッシュさせています。

FileManagerはファイルとディレクトリを管理するクラスです。
このクラスの1つのオブジェクトがアプリに割り当てられ、アプリのために予約されたストレージ スペース内のファイルやディレクトリを作成、削除、コピー、移動ができます。
このオブジェクトを参照するプロパティがFileManager.defaultです。

対象のファイルURL取得

フォルダURLにファイル名を追加して、ファイルURLとします。
ファイルに対しての操作は、このファイルURLを使用します。

ファイルの書き込み

Stringに標準で用意されているwriteメソッドを使って、ファイルに書き込みを行います。

引数(to)には書き込むファイルのURLを指定します。ファイルが存在しない場合は、生成されます。
引数(atomically)は、元のファイルが破損しないようにするために、データを最初に補助ファイルに保存するかどうかをBool値で指定します (true推奨)。
引数(encoding)は、文字列を生成するために使用されるエンコーディングタイプを指定します。
特別な事情が無い場合は、utf8にしておけば問題ありません。

このメソッドは、書き込みできない場合にエラーを返す為、do-try-catchでエラーハンドリングをしています。

ファイル読み込み処理の解説

①DocumentsフォルダURL取得、②対象のファイルURL取得はファイル書き込み処理と同様です。

ファイルの読み込み

特別なイニシャライザであるString(contentsOf :)を使用して、ファイルの内容を文字列にロードします。
このイニシャライザはロードできない場合にエラーを返す為、tryまたはtry?を使用して呼び出す必要があります。

fileContentsへの読み込みが成功したら、以降は通常の文字列として好きなように使用できます。

スポンサーリンク

実際のファイルを見る方法

アプリ内のフォルダにアクセスしてファイルを見る方法を3つ紹介します。

実機アプリのフォルダを開く方法

Xcodeのメニューから Windows>Devices and Simulators を選択し、次の画面を開きます。
Devices and Simulators

  1. Devicesを選択
  2. 対象の端末を選択
  3. 対象のアプリを選択
  4. 歯車アイコンをクリック

次のメニューが開くので、Download Containerを選択し、フォルダコンテナをMacにダウンロードします。
メニュー

ダウンロードしたファイルを右クリックし「パッケージの内容を表示」するとフォルダの内容が確認できます。
パッケージ内容の表示

シミュレータのフォルダを開く方法

現行のXcodeからはなぜかシミュレータのフォルダを開けないので、Finderで直接アクセスします。

シミュレーターのデータは、/Users/${USER}/Library/Developer/CoreSimulator/Devices/ にあります。

※Libraryは隠しフォルダになっていますので、Cmd + Shift + .(ピリオド)で表示させます。

各シミュレーターのフォルダ名はID形式になっています。またシミュレーター内の各アプリフォルダもID形式になっており、どれが対象のフォルダか容易にはわかりません。
ファイルの変更日である程度推測はできますが、確実なのはアプリに次のコードを埋め込んでフォルダのパスを表示させる方法です。

「ファイル」アプリからフォルダを開く方法

iOS11以降で搭載されたiOS標準の「ファイル」アプリを使うと、アプリのDocumentsフォルダにあるファイルを直接閲覧、編集、コピー等できます。

「ファイル」アプリからのアクセスを許可するには、info.plistの設定が必要です。

  • Xcode13.X以上を使用している場合は、こちらを参照して下さい。
  • iOS15.Xのシミュレーターでは下記の設定をしてもファイルアプリとの連携ができない不具合があるようですが実機では動作します。

info.plistの設定

info.listの設定

  1. Project navigatorで info.plist クリック
  2. 次の2行を追加し、Valueを YES にする
  • Application supports iTunes file sharing
  • Supports opening documents in place

※マウスポインタを適当なKey名の所に持っていくと画面のように、Key名の右側に「+(プラス)」と「ー(マイナス)」ボタンが現れるので、「+」をクリックで行を追加できます。

設定後アプリを再buildすると、ファイルアプリからアクセス可能になります。

ファイルアプリからのアクセス手順

  1. ファイルアプリをタップ
  2. タブメニューの「ブラウズ」をタップ
  3. 「このiPhone内」をタップ
  4. アクセス可能なアプリ一覧が表示される。対象アプリをタップ
  5. Documentsフォルダのファイル一覧が表示される。ファイルをタップ。
  6. ファイルの内容が表示される。

ファイルアプリからのアクセス手順

Xcode13.X以上の注意点

Xcode13から新規プロジェクト作成時にinfo.plistが生成されなくなりました。
代わりに、下記画面のinfoタブで同様の設定が行えます。

UntitledImage

スポンサーリンク

あわせて読みたい記事

【Swift】プロジェクト内のファイル読み込み
プロジェクトに含まれているリソースファイルにアクセスする方法を解説します。アプリ内のファイルシステムへアクセスする方法を知りたい方は、を御覧ください。
【Swift】プロジェクト内のJSONファイル読み込み
プロジェクトにリソースとしてバンドルされたJSONファイルを読み込む方法を解説します。リソースファイルではなく、アプリ内のファイルシステムにあるファイルにアクセスしたい場合は、 も合わせてご覧下さい。
【Swift】iOSアプリのフォルダ検索
iOSアプリのフォルダ検索方法について解説します。iOSアプリのファイルシステムについては、で解説していますので、あわせてそちらも御覧ください。
スポンサーリンク
swift
カピ通信