🦅

[iOSアプリ開発] ファイルを抽象化した構造体を作る(2)

2021/02/09に公開

こんにちは。
ZennではiOSアプリ開発の普段自分が使っているちょっとしたTipsなどを書いていければと思っております。

今回はSwiftでは少し冗長になりがちなファイルの操作を簡単にするために "ファイルを抽象化した構造体" を作っていきます。
当記事だけで終わりというわけではなく、続き物にしていく予定なのでよろしくおねがいします。

1つ目はこちら
https://zenn.dev/nkysyuichi/articles/467ddcc1041d4e

ファイルを取り扱う構造体

ファイルの存在確認

ファイルの存在確認は本来はこんな感じで取得できます。

FileManager.default.fileExists(atPath: "ファイルのパス")

まあ、これだとちょっと長いので、こんな感じで計算プロパティを作ってラップしておきます。

extension File {
    
    var exists: Bool {
        return FileManager.default.fileExists(atPath: path)
    }
}

使い方

let file = File.documentDirectory + "text.txt"
if file.exists {
    // ....
}

といったように書くことができます。シンプルでしょ。

親ディレクトリを取得できるようにする

現在指定されているパスの親ディレクトリを取得できるようにしておきます。

extension File {
    
    var parentDirectoryPath: String {
        if path == "/" { return "" }
        return (path as NSString).deletingLastPathComponent
    }
    
    var parentDirectory: File {
        return File(path: parentDirectoryPath)
    }
}

※パスがルートディレクトリ "/"だと deletingLastPathComponent のときににおかしな挙動をしてしまうので、こういう書き方になっています。

使い方

こういった書き方で同じディレクトリに置かれる兄弟ファイルを定義できるようになります。

let file1 = File.documentDirectory + "texts" + "001.txt"
let file2 = file1.parentDirectory + "002.txt"

// 同じディレクトリを指定できる
// (ドキュメントディレクトリ)/texts/001.txt
// (ドキュメントディレクトリ)/texts/002.txt

ディレクトリを作る仕組み

File構造体はパス文字列を持っているだけの存在です。
実際にディレクトリを指定していてもファイルシステム上はそのディレクトリが存在しているわけではありません。
なので、実際にディレクトリを作る仕組みをラップしていきます。

extension File {
    
    func makeDirectory() throws {
        if !exists {
            try FileManager.default.createDirectory(
                atPath: path,
                withIntermediateDirectories: true,
                attributes: nil
            )
        }
    }
}

先程つくったexistsも活躍しますね。

intermediateDirectoriesは、中間のディレクトリを作ってくれるか、もしくは存在しないとエラーにするかに分岐します。やりたいことによりますが、true固定でいいかなと思います。

https://developer.apple.com/documentation/foundation/filemanager/1407884-createdirectory

ここで初めてthrowsが出てきますが、これから先はファイル操作の実行系メソッドは throwsを宣言して、例外スローの可能性を実装者に示しておくとよいと思います。(try?などで吸収しないほうがよいです)

使い方

let dir = File.documentDirectory + "users" + "user1"
try? dir.makeDirectory()

これで (ドキュメントディレクトリ)/users/user1/ というディレクトリが実際に作られるはずです。

まとめ

ここまでで

  • ファイル(またはディレクトリ)の存在確認ができるようになった
  • 現在のパスの親ディレクトリを取得できるようになった
  • 実際にディレクトリを作る機能をつけた

というところまでやりました。

次回以降でまだまだ便利していきましょう。

ではまた。

Discussion