20

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..

Martin
  • 846
  • 1
  • 9
  • 23
mouni
  • 327
  • 1
  • 3
  • 15

4 Answers4

22

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.

Abhishek Mitra
  • 3,335
  • 4
  • 25
  • 46
  • Hi Abhishek then how to upload the document to the server. – mouni Dec 18 '17 at 10:00
  • @mouni well, it is very easy, if you can select document from `UIDocumentPickerViewController ` then you will get file path `print(url)` from above code of mine. and you need to look at this answer: https://stackoverflow.com/questions/47754252/how-to-open-a-link-to-a-pdf-with-wkwebview/47754483#47754483 Then that file need to upload like any other like to upload images into the server. – Abhishek Mitra Dec 18 '17 at 10:02
  • I have an error Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Application initializing document picker is missing the iCloud entitlement. Is com.apple.developer.icloud-container-identifiers set?' – mouni Dec 18 '17 at 10:10
  • @mouni when did you find the crash ? in which operation ? – Abhishek Mitra Dec 18 '17 at 10:13
  • I use uiactionsheet. when I click file action it will be crash. I my fileAction i can use let documentPicker = UIDocumentPickerViewController(documentTypes: ["public.text", "com.apple.iwork.pages.pages", "public.data"], in: .import) documentPicker.delegate = self present(documentPicker, animated: true, completion: nil) – mouni Dec 18 '17 at 10:17
  • @mouni turn off the iColoud thing, to do so, go through this image: https://imgur.com/a/ntubG – Abhishek Mitra Dec 18 '17 at 10:17
  • I all so off the iColoud. still I have an error *** Assertion failure in -[UIDocumentPickerViewController _commonInitWithCompletion:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3600.9.1/UIDocumentPickerViewController.m:91 Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Application initializing document picker is missing the iCloud entitlement. Is com.apple.developer.icloud-container-identifiers set?' – mouni Dec 18 '17 at 10:20
  • @mouni well in that case i need to look into your code, else it will be not possible to solve this by seeing only this error msg. – Abhishek Mitra Dec 18 '17 at 10:22
  • can you please try this link [https://www.dropbox.com/s/f3i4k5f61rbnuko/AddressProofVC.swift?dl=0] – mouni Dec 18 '17 at 11:01
  • @mouni when did you finding the crash ? when you calling `actionSheet` delegate method, at that time? Here I can not compile your code by this way. – Abhishek Mitra Dec 18 '17 at 11:05
  • I click File button the crash. – mouni Dec 18 '17 at 11:07
  • func OpenFile(){ } function. the takefile() is no need it. I hide the function. – mouni Dec 18 '17 at 11:11
  • Well, according to your code you are calling your `OpenFile()` from `actionSheet`, and when `OpenFile()` get called, it get crashed according to you. Well here i did not find anything unusual, except you can try `DispatchQueue.main.async { print("Async1") }` Also, can you say if compiler entering in `didPickDocumentAt` this delegate method ? – Abhishek Mitra Dec 18 '17 at 11:18
  • @mouni you can try this `func OpenFile(){ self.dismiss(animated: true, completion: nil) let documentPicker = UIDocumentPickerViewController(documentTypes: ["public.text", "com.apple.iwork.pages.pages", "public.data"], in: .import) documentPicker.delegate = self present(documentPicker, animated: true, completion: nil) }` Replace this code with your `OpenFile(){}` – Abhishek Mitra Dec 18 '17 at 11:24
  • I replace it but still Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Application initializing document picker is missing the iCloud entitlement. Is com.apple.developer.icloud-container-identifiers set?' – mouni Dec 18 '17 at 11:26
  • @mouni well without compiling it is impossible to detect the main problem. At least I can't. – Abhishek Mitra Dec 18 '17 at 11:27
  • Thank you so much I got it... finally I on the iCloud Driver. it's working fine. thank you Abhishek :) – mouni Dec 18 '17 at 11:47
  • How can we make single selection enable ? Making documentPicker.allowsMultipleSelection = true is only making select all documents at once but how can we enable single and multiple selection with those side thumbnails as default property of image selection as well in iOS ? – Neeraj Shukla Feb 20 '21 at 07:27
17

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)
halfer
  • 19,824
  • 17
  • 99
  • 186
Himanshu padia
  • 7,428
  • 1
  • 47
  • 45
15

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.

Umar Farooque
  • 2,049
  • 21
  • 32
1

UIDocumentPickerViewController.init(documentTypes:in:) and kUTType___ were deprecated in iOS 14 and 15 respectively. Here's how to achieve the same on newer versions of iOS:

let contentTypes: [UTType] = [
    .init(filenameExtension: "doc")!,
    .init(filenameExtension: "docx")!,
    .pdf
]

let documentPicker = UIDocumentPickerViewController.init(forOpeningContentTypes: contentTypes)
documentPicker.delegate = self
present(documentPicker, animated: true)
Breiby
  • 554
  • 5
  • 14