-
-
Save MMnasrabadi/c55a53840752d40646b9269c4321410b to your computer and use it in GitHub Desktop.
UIDocumentPickerViewController example in Swift 5. Bug fixed version of this article: https://medium.com/flawless-app-stories/a-swifty-way-to-pick-documents-59cad1988a8a
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// DocumentPicker.swift | |
import UIKit | |
import MobileCoreServices | |
protocol DocumentDelegate: class { | |
func didPickDocument(document: Document?) | |
} | |
class Document: UIDocument { | |
var data: Data? | |
override func contents(forType typeName: String) throws -> Any { | |
guard let data = data else { return Data() } | |
return try NSKeyedArchiver.archivedData(withRootObject:data, | |
requiringSecureCoding: true) | |
} | |
override func load(fromContents contents: Any, ofType typeName: | |
String?) throws { | |
guard let data = contents as? Data else { return } | |
self.data = data | |
} | |
} | |
open class DocumentPicker: NSObject { | |
private var pickerController: UIDocumentPickerViewController? | |
private weak var presentationController: UIViewController? | |
private weak var delegate: DocumentDelegate? | |
private var pickedDocument: Document? | |
init(presentationController: UIViewController, delegate: DocumentDelegate) { | |
super.init() | |
self.presentationController = presentationController | |
self.delegate = delegate | |
} | |
public func displayPicker() { | |
/// pick movies and images | |
self.pickerController = UIDocumentPickerViewController(documentTypes: [kUTTypeMovie as String, kUTTypeImage as String], in: .import) | |
self.pickerController!.delegate = self | |
self.presentationController?.present(self.pickerController!, animated: true) | |
} | |
} | |
extension DocumentPicker: UIDocumentPickerDelegate { | |
/// delegate method, when the user selects a file | |
public func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) { | |
guard let url = urls.first else { | |
return | |
} | |
documentFromURL(pickedURL: url) | |
delegate?.didPickDocument(document: pickedDocument) | |
} | |
/// delegate method, when the user cancels | |
public func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) { | |
delegate?.didPickDocument(document: nil) | |
} | |
private func documentFromURL(pickedURL: URL) { | |
/// start accessing the resource | |
let shouldStopAccessing = pickedURL.startAccessingSecurityScopedResource() | |
defer { | |
if shouldStopAccessing { | |
pickedURL.stopAccessingSecurityScopedResource() | |
} | |
} | |
NSFileCoordinator().coordinate(readingItemAt: pickedURL, error: NSErrorPointer.none) { (readURL) in | |
let document = Document(fileURL: readURL) | |
pickedDocument = document | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ViewController.swift | |
class ViewController: UIViewController, DocumentDelegate { | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
/// set up the document picker | |
documentPicker = DocumentPicker(presentationController: self, delegate: self) | |
} | |
/// callback from the document picker | |
func didPickDocument(document: Document?) { | |
if let pickedDoc = document { | |
let fileURL = pickedDoc.fileURL | |
/// do what you want with the file URL | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment