BLOG

ブログ

2022/09/12 技術系

iOSの標準ファイルアプリのファイル読み込みで困ったこと

この記事を書いた人 M.H

こんにちは!M.Hです。
今回は、iOS標準のファイルアプリを使用してファイルを読み込んだ際に起きた困ったことについて書きたいと思います。

環境

  • MacBook Pro (13-inch, M1, 2020)
  • macOS Monterey 12.5
  • Xcode version 13.4.1
  • Swift version 5.6.1
  • iPad Air (第4世代)
  • iPadOS 15.6

やりたいこと

iOS標準ファイルアプリと連携してiPadのストレージやUSBメモリからのファイル読み込み。
今回の場合だと、フォルダを選択してその中のファイルをアプリに読み込ませる流れ。

アプリから標準ファイルアプリを開く方法

UIDocumentPickerViewControllerを使用することで簡単にファイルを読み込めるようになります。
USBメモリ内のファイルを読み込む際はセキュリティリソースへのアクセスが必要です。
ファイルへの処理が終了したあとはセキュリティリソースの解放を推奨です。
参考:https://developer.apple.com/documentation/uikit/uidocumentpickerviewcontroller

class ViewController: UIViewController { 

    // 省略

    /// 読み込みボタンをタップ
    @IBAction func tapFileReadButton(_ sender: Any) {
        // フォルダのみ選択できるドキュメントピッカーを作成
        if #available(iOS 14.0, *) {
            let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: [.folder])
            documentPicker.delegate = self
            present(documentPicker, animated: true, completion: nil)
        } else {
            let documentPicker = UIDocumentPickerViewController(documentTypes: [String(kUTTypeFolder)], in: .open)
            documentPicker.delegate = self
            present(documentPicker, animated: true, completion: nil)
        }
    }
}

/// UIDocumentPickerDelegate
extension ViewController: UIDocumentPickerDelegate {
    /// ファイル選択後に呼ばれる
    func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
        // URLを取得
        guard let url = urls.first else { return }
        // USBメモリなど外部記憶装置内のファイルにアクセスするにはセキュリティで保護されたリソースへのアクセス許可が必要
        guard url.startAccessingSecurityScopedResource() else {
            // ここで選択したURLでファイルを処理する
            return
        }
        // ファイルの処理が終わったら、セキュリティで保護されたリソースを解放
        defer { url.stopAccessingSecurityScopedResource() }
    }
}

困ったところ

  • 起きたこと
    USBメモリからのファイル読み込みができない。
  • 原因
    .hasDirectoryPathでURLがディレクトリかどうかをチェックしていて、USBメモリ内で選択した場所のURLがディレクトリ扱いになっていなかった。
    それが原因でURLがディレクトリかどうかを判定するif文をスルーしていた。
// USBメモリ内からParameter選択した場合のURL
// 例)"file:/// ~ /Parameter" ←これだとディレクトリとして認識されない

// iPad内からParameter選択した場合のURL
// 例)"file:/// ~ /Parameter/" ←これはディレクトリとして認識される

// 選択したURLがディレクトリかどうか
if url.hasDirectoryPath {
   // ここで読み込む処理
}
  • 対応
    対応として、ディレクトリチェックのif文を削除しました。
    元々ドキュメントピッカーで選択できる対象をフォルダに限定していたため、よくよく考えてみると不要な処理でした。
  • 結果
    上記の対応を行うことで無事USBメモリからもファイルが読み込めるようになりました。

まとめ

今回は無駄な処理を書いていたことでファイルが読み込めなくなっていました。
ただ、iPad内からとUSBメモリからでURLに違いが出るのは謎な所なので、今後調べていきたいと思います!
今後もこういった変なミスを減らして、作業効率を上げていけるよう頑張っていきます!



株式会社ウイングドアは福岡のシステム開発会社です。
現在、私達と一緒に"楽しく仕事が出来る仲間"として、新卒・中途採用を絶賛募集しています!
ウイングドアの仲間達となら楽しく仕事できるかも?と興味をもった方、
お気軽にお問い合わせ下さい!

アーカイブ