I am new into this Xcode iOS stuff, I am trying to build a file uploader, you pick a file and then you upload to server. Currently I am stuck at picking the file. I have used some code found on this website, but I am getting some errors.
Class starts like this:
class DocumentsController: UIViewController, UIDocumentMenuDelegate,UIDocumentPickerDelegate,UINavigationControllerDelegate
Methods used are:
#objc func pickFile() {
let importMenu = UIDocumentMenuViewController(documentTypes: [String(kUTTypePDF), String(kUTTypePNG), String(kUTTypeJPEG)], in: .import)
importMenu.delegate = self
importMenu.modalPresentationStyle = .formSheet
self.present(importMenu, animated: true, completion: nil)
}
public func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard let myURL = urls.first else {
return
}
print("import result : \(myURL)")
}
public func documentMenu(_ documentMenu:UIDocumentMenuViewController, didPickDocumentPicker documentPicker: UIDocumentPickerViewController) {
documentPicker.delegate = self
present(documentPicker, animated: true, completion: nil)
}
func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
print("view was cancelled")
dismiss(animated: true, completion: nil)
}
In the documentPicker method I have two errors:
'URL' is ambiguous for type lookup in this context <- for urls: [URL]
Type of expression is ambiguous without more context <- for guard let myURL = urls.first
If I replace URL with String or NSURL it gets past that, the build is successful, the app on the simulator is running (Iphone 8 plus), I can open the picker, choose a file, but then nothing happens. It just closes the picker and that's it. documentPicker method doesn't trigger. Out of the 4 methods only pickFile and documentMenu are triggering.
Xcode version is 13.3.1
Delegate method are not working for UIDocumentPickerViewController
from upload action want to load document from simulator for uploading to other action...
func uploadFile(){
let documentPickerController = UIDocumentPickerViewController(documentTypes: [String(kUTTypePDF), String(kUTTypeImage), String(kUTTypeMovie), String(kUTTypeVideo), String(kUTTypePlainText), String(kUTTypeMP3)], in: .import)
documentPickerController.delegate = self
present(documentPickerController, animated: true, completion: nil)
}
On selected didPickDocumentPicker noting happening in swift 5.0
extension UIViewController: UIDocumentMenuDelegate,UIDocumentPickerDelegate,UINavigationControllerDelegate
{
public func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard let myURL = urls.first else {
return
}
print("import result : \(myURL)")
let fileName = urls.first?.lastPathComponent
print(fileName)
// self.loadUploadView(selectedFile: fileName!)
}
func documentMenu(_ documentMenu:UIDocumentMenuViewController, didPickDocumentPicker documentPicker: UIDocumentPickerViewController) {
documentPicker.delegate = self
present(documentPicker, animated: true, completion: nil)
}
func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
print("view was cancelled")
dismiss(animated: true, completion: nil)
}
}
For Device its working fine but for simulator its not working
else for iOS versions 13 its not working.
Device Version is 14
Simulator versions is 13.
I need to open UIDocumentPickerViewController and It should allow user to select all type of files. ie.(.pdf,.doc)files I used UIDocumentPickerViewController method.
my Code:
UIDocumentPickerDelegate, UIDocumentMenuDelegate in my class declaration
//upload file
func OpenFile(){
let importMenu = UIDocumentMenuViewController(documentTypes: [String(kUTTypePNG),String(kUTTypeImage)], in: .import)
importMenu.delegate = self
importMenu.modalPresentationStyle = .fullScreen
self.present(importMenu, animated: true, completion: nil)
}
#available(iOS 8.0, *)
public func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
let cico = url as URL
print("The Url is : \(cico)")
do {
let weatherData = try NSData(contentsOf: cico, options: NSData.ReadingOptions())
print(weatherData)
let activityItems = [weatherData]
let activityController = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
if UI_USER_INTERFACE_IDIOM() == .phone {
self.present(activityController, animated: true, completion: { _ in })
}
else {
let popup = UIPopoverController(contentViewController: activityController)
popup.present(from: CGRect(x: CGFloat(self.view.frame.size.width / 2), y: CGFloat(self.view.frame.size.height / 4), width: CGFloat(0), height: CGFloat(0)), in: self.view, permittedArrowDirections: .any, animated: true)
}
} catch {
print(error)
}
//optional, case PDF -> render
//displayPDFweb.loadRequest(NSURLRequest(url: cico) as URLRequest)
}
#available(iOS 8.0, *)
public func documentMenu(_ documentMenu: UIDocumentMenuViewController, didPickDocumentPicker documentPicker: UIDocumentPickerViewController) {
documentPicker.delegate = self
present(documentPicker, animated: true, completion: nil)
}
func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
print(" cancelled by user")
dismiss(animated: true, completion: nil)
}
In this code the app will crash. the reason is Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'You cannot initialize a UIDocumentPickerViewController except by the initWithDocumentTypes:inMode: and initWithURL:inMode: initializers.
I don't know how to initialise the initWithDocumentTypes:inMode. I'm new to iOS any one help me???
can you please help me..
Swift 3*, 4*,
To open document and select any document, you are using UIDocumentPickerViewController then all documents presented in your iCloud, Files and in Google Drive will be shown if Google Drive is connected in user device. Then selected document need to download in your app and from there you can show it in WKWebView,
#IBAction func uploadNewResumeAction(_ sender: Any) {
/* let documentPicker = UIDocumentPickerViewController(documentTypes: ["com.apple.iwork.pages.pages", "com.apple.iwork.numbers.numbers", "com.apple.iwork.keynote.key","public.image", "com.apple.application", "public.item","public.data", "public.content", "public.audiovisual-content", "public.movie", "public.audiovisual-content", "public.video", "public.audio", "public.text", "public.data", "public.zip-archive", "com.pkware.zip-archive", "public.composite-content", "public.text"], in: .import) */
let documentPicker = UIDocumentPickerViewController(documentTypes: ["public.text", "com.apple.iwork.pages.pages", "public.data"], in: .import)
documentPicker.delegate = self
present(documentPicker, animated: true, completion: nil)
}
extension YourViewController: UIDocumentPickerDelegate{
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
let cico = url as URL
print(cico)
print(url)
print(url.lastPathComponent)
print(url.pathExtension)
}
}
Note: If you intend to select all files the you have to use following code:
let documentPicker = UIDocumentPickerViewController(documentTypes: ["com.apple.iwork.pages.pages", "com.apple.iwork.numbers.numbers", "com.apple.iwork.keynote.key","public.image", "com.apple.application", "public.item","public.data", "public.content", "public.audiovisual-content", "public.movie", "public.audiovisual-content", "public.video", "public.audio", "public.text", "public.data", "public.zip-archive", "com.pkware.zip-archive", "public.composite-content", "public.text"], in: .import)
In your action method.
To open the specific document files of (.pdf, .doc, .docx) using UIDocumentPickerViewController in Swift:
documentTypes would be
import import MobileCoreServices
["com.microsoft.word.doc","org.openxmlformats.wordprocessingml.document", kUTTypePDF as String]
Example:
let importMenu = UIDocumentPickerViewController(documentTypes: ["com.microsoft.word.doc","org.openxmlformats.wordprocessingml.document", kUTTypePDF as String], in: UIDocumentPickerMode.import)
importMenu.delegate = self
self.present(importMenu, animated: true, completion: nil)
Actually, instead of WebView you could also use the QuickLook
Framework, which is designed for this specific purpose. You just pass
the location of the file and conform to the protocols. It will present
a view controller with the document inside.
It supports the following file:
- iWork documents (Pages, Numbers and Keynote)
- Microsoft Office documents (as long as they’ve been created with Office 97 or any other newer version)
- PDF files
- Images
- Text files
- Rich-Text Format documents
- Comma-Separated Value files (csv)
Here is a tutorial by APPCODA, that describes the same.
and
Here is the tutorial provided by Apple OBJ-C version.
In my app I picked files by UIDocumentPicker and put file names on a tableView. When clicking on a cell, I want the app open the file. I have no idea how to open the files picked before. Please help.
import UIKit
extension ViewController: UIDocumentMenuDelegate {
func documentMenu(documentMenu: UIDocumentMenuViewController, didPickDocumentPicker documentPicker: UIDocumentPickerViewController) {
documentPicker.delegate = self
self.presentViewController(documentPicker, animated: true, completion: nil)
}
}
extension ViewController: UIDocumentPickerDelegate {
func documentPicker(controller: UIDocumentPickerViewController, didPickDocumentAtURL url: NSURL) {
if controller.documentPickerMode == UIDocumentPickerMode.Import {
dispatch_async(dispatch_get_main_queue()) {
if let fileName = url.lastPathComponent {
self.files.append(fileName)
}
}
}
}
}
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var files = [AnyObject]()
#IBOutlet weak var fileTableView: UITableView!
#IBAction func addDocuments(sender: AnyObject) {
let importMenu = UIDocumentMenuViewController(documentTypes: ["public.data", "public.text"], inMode: .Import)
importMenu.delegate = self
self.presentViewController(importMenu, animated: true, completion: nil)
let documentPicker = UIDocumentPickerViewController(documentTypes: ["public.data", "public.text"], inMode: .Import)
documentPicker.delegate = self
documentPicker.modalPresentationStyle = UIModalPresentationStyle.FullScreen
self.presentViewController(documentPicker, animated: true, completion: nil)
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
}
You need to keep a reference to the entire URL, not just the filename.
Add the full url to self.files. Then update your cellForRowAtIndexPath to show just the lastPathComponent of that URL.
Then in didSelectRowAtIndexPath you have the access to the full URL of the file.
I am following Apple documentation for UIDocumentMenuViewController and the following is my code. importMenu.delegate = self doesn't work and Xcode shows: Cannot assign value of type 'ViewController' to type 'UIDocumentMenuDelegate?' . Please help. Thanks!
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let importMenu = UIDocumentMenuViewController(documentTypes: ["public.text", "public.data"], inMode: .Import)
importMenu.delegate = self
self.presentViewController(importMenu, animated: true, completion: nil)
}
}
According to UIDocumentMenuDelegate Protocol Reference, your ViewController must conforms to UIDocumentMenuDelegate and must implements documentMenu:didPickDocumentPicker:
extension ViewController: UIDocumentMenuDelegate {
func documentMenu(documentMenu: UIDocumentMenuViewController, didPickDocumentPicker documentPicker: UIDocumentPickerViewController) {
// do stuffs here
}
}
your delegation class should extend from UIDocumentMenuViewDelegate in the view controller
import UIKit
class ViewController: UIViewController, UIDocumentMenuViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let importMenu = UIDocumentMenuViewController(documentTypes: ["public.text", "public.data"], inMode: .Import)
importMenu.delegate = self
self.presentViewController(importMenu, animated: true, completion: nil)
}
}