8
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

LIFULLAdvent Calendar 2021

Day 2

【Swift】ファイル操作で保存されたファイルやパスを色んな形式で確認してみる

Last updated at Posted at 2021-12-01

はじめに

※この記事は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 > [日付のディレクトリ] > [なんらかの動画ファイル]という構成になることは決まっていたので、contentUrlPathFileNameを取得し、それらを文字列として連結させ、URLに変えてあげる。。をすれば最低限動画の再生には持って行けました。

これは若干力技なので、Documentディレクトリから再帰的にディレクトリじゃなくなるまでファイルを検索しにいくようにするとファイルの構成が異なったりしていても柔軟に動画ファイルのURLを取得できてスマートかなと思ったりしました。

また、地味にcontentUrlcontentUrl.pathの違いでも詰まりました。
.pathはあくまでファイルパスの文字列を返すだけなので、これを使えば動画再生ができると思いましたが、URLではないので動画をそのまま使いたい場合は間違えずにURL型のcontentUrlの方を使ってあげましょう。

終わりに

今回はSwiftでファイルの作成や取得をする際に、必要な情報をどう取得するべきかを、簡単にコーディングをしながらまとめてみました。
今回得た知見を活かしてファイルの取り扱いをうまくやっていきながらアプリ開発していけるようにしたいですね。

また、ここら辺参考になるよとか、言ってること違うよとかがあればコメントいただけると幸いです。
僕の書いた本文と、コメント欄で一つの作品とさせていただければと思います。

参照

  1. いまさらだけどiOSのファイル操作まとめ(Swift) - Qiita
  2. Documentフォルダにファイルを保存する – 野生のプログラマZ
  3. Swiftでパスからファイル名や拡張子を取得する方法
  4. ファイルPathとファイルURL - アプリ開発ブログ(仮)
8
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?