この記事では、アプリ内のファイル(ストレージ)に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)") } }