SwiftUIの基本を身につけたい方はこちら

【Xcode/Swift】アプリ内のファイルにFileManager書き込んで保存したり、取得する方法

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

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

FileManagerの使い方

UI作成

まずは、簡単にUIを作成します。

STEP.1
オブジェクトを配置

TextFieldとButtonを配置します。

ボタンの名前は、それぞれ「書き込み」と「読み込み」にしておいてください。

AutoLayoutは今回は省きます。

STEP.2
紐付け

それぞれ紐付けます。

@IBOutlettextFieldという名前で紐付け
@IBActionwritingButtonActionという名前で紐付け
@IBActionreadButtonActionという名前で紐付け

UIはこれでOKです。

書き込む方法

STEP.1
書き込む処理を追加

まずは、書き込む処理を追記します。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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 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 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で書き込んでいます。

STEP.2
処理を呼ぶ

次に、追記した関数を呼び出します。writingButtonActionに以下のコードを追記します。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
guard let text = textField.text else { return }
writingToFile(text: text)
guard let text = textField.text else { return } writingToFile(text: text)
guard let text = textField.text else { return }
writingToFile(text: text)

これでファイルに書き込めました。

読み込む方法

次に、書き込んだファイルを読み込みましょう。やり方としては、書き込むのと同じ感じでできます。

STEP.1
読み込む処理を追加
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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 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 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で返しています。

STEP.2
処理を呼ぶ

次に、追記した関数を呼び出します。readButtonActionに以下のコードを追記します。

文字列で返ってくるので今回は、適当にprintさせてみましょう。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
print("ファイル内容:\(readFromFile())")
print("ファイル内容:\(readFromFile())")
print("ファイル内容:\(readFromFile())")
STEP.3
実行して確認

TextFieldに適当な値を入力して、「書き込む」ボタンを押してから、「読み込む」ボタンを押すと、コンソールに入力した文字列が表示されるかと思います。

これで、読み込みができました。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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
}
}
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 } }
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
    }
}

書き足す方法

ちなみに、書き足す方法は、以下のように書きます。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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)")
}
}
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)") } }
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)")
    }
}

評価