0
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?

【SwiftUI】SwiftUIでUIDocumentPickerViewControllerを初めて使ってみた

Posted at

実現しようとしたこと

  • 端末の中に保存されているファイルのアップロードを実現しようとした
  • 下から画面がにゅっと出てきて端末の中に保存されているファイル一覧が表示される処理を実現しようとした

方針

  • どうやらUIDocumentPickerViewControllerなるものを使うことでそれが実現できるらしい
  • SwiftUIにはそれを実現できる方法がないのでUIKitUIDocumentPickerViewControllerというコントローラーをViewControllerRepresentableを用いてラップすることで、むりくり実現が出来る。

解決策

DocumentPickerクラスの準備

  • 事前準備として、DocumentPickerというクラスを準備しておく。
DocumentPicker.swift
import SwiftUI
import UIKit
import UniformTypeIdentifiers

struct DocumentPicker: UIViewControllerRepresentable {
    var onPick: (URL) -> Void
    
    func makeUIViewController(context: Context) -> some UIViewController {
        let picker = UIDocumentPickerViewController(forOpeningContentTypes: [.item], asCopy: true)
        picker.delegate = context.coordinator
        picker.allowsMultipleSelection = false
        return picker
    }
    
    func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {}
    
    func makeCoordinator() -> Coordinator {
        Coordinator(onPick: onPick)
    }
    
    class Coordinator: NSObject, UIDocumentPickerDelegate {
        var onPick: (URL) -> Void
        
        init(onPick: @escaping (URL) -> Void) {
            self.onPick = onPick
        }
        
        func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
            onPick(urls.first!)
        }
    }
}


  • makeUIViewControllerでは端末からDocument一覧画面を開き、delegateCoordinatorを指定する。
  • Coorindatorの中ではアイテムがPickされた時のアイテムの登録処理の指定を行う
  • Coordinatordelegate を橋渡しして画面にURLを返す

というのが大体の流れになります

Viewから呼び出す

ContentView.swift
 @State private var selectedFileURL: URL?
 // 省略
 .sheet(isPresented: $showPicker) {
    DocumentPicker { url in
        selectedFileURL = url
        // do something
    }
}
  • あとはViewからurlを取得することができるので任意の操作を行うという流れになります。

  • UIViewRepresentableだとmakeUIView updateUIViewとなるのに、それのController版だとmakeUIViewController updateUIViewControllerになるのがかわいいなと思いました
0
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
0
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?