ファイル追記書き込み(Swift)

Swiftっぽくファイルの書き込みをする方法

iOSでファイルへの追記書き込みをしたい場合、

というのが、ググるとよく出てくる方法である

上記の方法自体は間違っていないが、ファイルへの書き込みが失敗した(writeを実行したらエラーが発生した)場合のエラーが戻り値ではなく、例外で投げられてしまうという問題がある

しかも、この時に投げられる例外はSwiftの例外ではキャッチできないタイプとなっている

もちろん、こういった方法を使えばキャッチできなくはないが、正直、面倒である

という訳で、いろいろ探してたどり着いたのがOutputStreamを使う方法

ソース

メソッドにすると以下のような感じ

func write(url: URL, text: String) -> Bool {
guard let stream = OutputStream(url: url, append: true) else {
return false
}
stream.open()
defer {
stream.close()
}
guard let data = text.data(using: .utf8) else { return false }
let result = data.withUnsafeBytes {
stream.write($0, maxLength: data.count)
}
return (result > 0)
}
view raw new_gist_file_0 hosted with ❤ by GitHub

解説

2行目で書き込み用のストリームを作成する時に、appendで追記書き込みを指定している。 なお、ここをfalseにすると通常のファイル書き込みに、trueにすると追記になる

7~9行目ではdeferを使ってclose処理を予約している。 これにより以降の処理でこのメソッドを抜ける(例えば11行目でreturn falseになった)時に、自動的にdeferの中のstream.close()が実行される

deferは書かれた直後から有効になるので、openの直後に書いておくのがポイント。 これにより、ファイルのクローズ処理漏れがなくなる

13~15行目で書き込み処理。 writeはポインタでデータを受け取り結果を返すのでこういう書き方になる

本当はちゃんとSwiftで例外を受け取れる様になれば一番良いのだけど・・・

開発環境