はじめに
※この記事はLIFULL Advent Calendar 2021の2日目の記事となります。
個人でiOSアプリ開発をしているときに、アプリ内でファイル操作をしたいときがあって、ほしい値を見たい時にどれを参照するのかがごっちゃになるのでまとめました。
前提
今回はDocumentディレクトリに日付のディレクトリを作成し、その中に動画ファイルがあるという状態で考えました。
※↓の階層はDocumentから始まっていますが、実際にはもっと階層は上にもあります。
Document/
├── 20211124/
│ ├── hogehoge.mov
│ └── fugafuga.mov
└── 20211126/
├── hogehoge.mov
└── hugahuga.mov
準備
ディレクトリ作成
今回はDocumentsディレクトリに作成します。
guard let documentDirectoryURL = FileManager.default.urls(for: .documentDirectory,
in: .userDomainMask).first else {
return
}
// ひとまず日付を直撃ちしてディレクトリ名を作成する
// ex.20211124とか
let directory = directory.appendingPathComponent("[ディレクトリ名]", isDirectory: true)
do {
try fileManager.createDirectory(at: directory, withIntermediateDirectories: true, attributes: nil)
} catch {
print("失敗した")
}
ファイル作成
作成したディレクトリにファイルを追加します。
ハードコーディング気味です。
// ディレクトリ名を直撃ちしています
let directoryPath = documentDirectoryURL.absoluteString + "20211124"
guard let targetDirectory = URL(string: directoryPath) else {
return
}
// ディレクトリのURLにファイル名を追加する
// これで ~~~~~/Document/20211124/hogehogeみたいなURLのファイルを作成できる
let fileName = "hogehoge"
let fileURL = targetDirectory.appendingPathComponent(fileName)
// 省略 fileURLを用いてrecordする
#パスやファイル名の取得
let fileManager = FileManager.default
let documentDirectoryURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!
do {
// Documentから動画ファイルのURLを取得
// 今回はURLの一つに対しての値をいくつか見る
guard let contentUrl = try fileManager.contentsOfDirectory(at: documentDirectoryURL,
includingPropertiesForKeys: nil).first else {
return
}
print("contentUrl: \(contentUrl)")
print("contentUrlPath: \(contentUrl.path)")
print("contentUrlLastPathComponent: \(contentUrl.lastPathComponent)")
print("FileName: \(try FileManager.default.contentsOfDirectory(atPath: contentUrl.path))")
} catch {
print("フォルダが空です。")
}
これを実行するとコンソールにprint文の結果が以下のように表示されます。
contentUrl: file:///private/var/mobile/Containers/Data/Application/FBAC66B0-F8EF-4689-8379-EE961C62E00B/Documents/20211124/
contentUrlPath: /private/var/mobile/Containers/Data/Application/FBAC66B0-F8EF-4689-8379-EE961C62E00B/Documents/20211124
contentUrlLastPathComponent: 20211124
FileName: ["hogehoge.mov"]
動画の再生をするにはファイルのURLが必要で、最初contentUrl.path
で取れるかと思っていました。
しかし、今回のcontentUrl
はDocumentディレクトリの一個下にある階層のコンテンツになるので、20211124ディレクトリまでの情報は取得できますが、そのさらに一個下の階層にあるhogehoge.movの情報はこれだけだと取得できませんでした。
これによって動画の再生ができなくて詰まっていました。
今回は前提としてDocument > [日付のディレクトリ] > [なんらかの動画ファイル]
という構成になることは決まっていたので、contentUrlPath
とFileName
を取得し、それらを文字列として連結させ、URLに変えてあげる。。をすれば最低限動画の再生には持って行けました。
これは若干力技なので、Documentディレクトリから再帰的にディレクトリじゃなくなるまでファイルを検索しにいくようにするとファイルの構成が異なったりしていても柔軟に動画ファイルのURLを取得できてスマートかなと思ったりしました。
また、地味にcontentUrl
とcontentUrl.path
の違いでも詰まりました。
.path
はあくまでファイルパスの文字列を返すだけなので、これを使えば動画再生ができると思いましたが、URLではないので動画をそのまま使いたい場合は間違えずにURL型のcontentUrlの方を使ってあげましょう。
終わりに
今回はSwiftでファイルの作成や取得をする際に、必要な情報をどう取得するべきかを、簡単にコーディングをしながらまとめてみました。
今回得た知見を活かしてファイルの取り扱いをうまくやっていきながらアプリ開発していけるようにしたいですね。
また、ここら辺参考になるよとか、言ってること違うよとかがあればコメントいただけると幸いです。
僕の書いた本文と、コメント欄で一つの作品とさせていただければと思います。