この記事では、アプリ内のファイル(ストレージ)にFileManagerで読み書きする方法について解説していきます。

このような、ファイルへの書き込みと読み込みができる、簡単なアプリを作りながら解説していきたいと思います。
FileManagerの使い方
UI作成
まずは、簡単にUIを作成します。

TextFieldとButtonを配置します。
ボタンの名前は、それぞれ「書き込み」と「読み込み」にしておいてください。
AutoLayoutは今回は省きます。

それぞれ紐付けます。
①@IBOutletでtextFieldという名前で紐付け
②@IBActionでwritingButtonActionという名前で紐付け
③@IBActionでreadButtonActionという名前で紐付け
UIはこれでOKです。
書き込む方法
まずは、書き込む処理を追記します。
func writingToFile(text: String) {
guard let dirURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
fatalError("フォルダURL取得エラー")
}
let fileURL = dirURL.appendingPathComponent("sample.txt")
do {
try text.write(to: fileURL, atomically: true, encoding: .utf8)
} catch {
print("failed to write: \(error)")
}
}

やってることとしては、FileManager.default.urlsで、Documentsフォルダを取得し、
dirURL.appendingPathComponent("sample.txt")で、sample.txtという名前でテキストファイルを作成し、追加しています。
そして、そのファイルに、text.writeで書き込んでいます。
次に、追記した関数を呼び出します。writingButtonActionに以下のコードを追記します。
guard let text = textField.text else { return }
writingToFile(text: text)

これでファイルに書き込めました。
読み込む方法
次に、書き込んだファイルを読み込みましょう。やり方としては、書き込むのと同じ感じでできます。
func readFromFile() -> String {
guard let dirURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
fatalError("フォルダURL取得エラー")
}
let fileURL = dirURL.appendingPathComponent("sample.txt")
guard let fileContents = try? String(contentsOf: fileURL) else {
fatalError("ファイル読み込みエラー")
}
return fileContents
}

書き込みと同じくフォルダにアクセスして、dirURL.appendingPathComponent("sample.txt")で、sample.txtを取得しています。
そして、その中身をreturnで返しています。
次に、追記した関数を呼び出します。readButtonActionに以下のコードを追記します。
文字列で返ってくるので今回は、適当にprintさせてみましょう。
print("ファイル内容:\(readFromFile())")
TextFieldに適当な値を入力して、「書き込む」ボタンを押してから、「読み込む」ボタンを押すと、コンソールに入力した文字列が表示されるかと思います。

これで、読み込みができました。
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func writingButtonAction(_ sender: Any) {
guard let text = textField.text else { return }
writingToFile(text: text)
}
@IBAction func readButtonAction(_ sender: Any) {
print("ファイル内容:\(readFromFile())")
}
func writingToFile(text: String) {
guard let dirURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
fatalError("フォルダURL取得エラー")
}
let fileURL = dirURL.appendingPathComponent("sample.txt")
do {
try text.write(to: fileURL, atomically: true, encoding: .utf8)
} catch {
print("failed to write: \(error)")
}
}
func readFromFile() -> String {
guard let dirURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
fatalError("フォルダURL取得エラー")
}
let fileURL = dirURL.appendingPathComponent("sample.txt")
guard let fileContents = try? String(contentsOf: fileURL) else {
fatalError("ファイル読み込みエラー")
}
return fileContents
}
}
書き足す方法
ちなみに、書き足す方法は、以下のように書きます。
func appendText(string: String) {
guard let dirURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
fatalError("フォルダURL取得エラー")
}
let fileURL = dirURL.appendingPathComponent("sample.txt")
do {
let fileHandle = try FileHandle(forWritingTo: fileURL)
let stringToWrite = "\n" + string
fileHandle.seekToEndOfFile()
fileHandle.write(stringToWrite.data(using: String.Encoding.utf8)!)
} catch let error as NSError {
print("Error: \(error)")
}
}

