How to use UIDocumentInteractionController?

Faisal picture Faisal · Jan 30, 2018 · Viewed 14.9k times · Source

I have created a program that loads PDF files. I want when the user is editing that they can publish the file anywhere in PDF format.

Do I use UIDocumentInteractionController or use UIActivityViewController?

Here is the code:

import UIKit
import PDFKit

@available(iOS 11.0, *)
@available(iOS 11.0, *)

class PDFViewControllerEN: UIViewController {
    var document: UIDocumentInteractionController!

    override func viewDidLoad() {
        super.viewDidLoad()
        // retrieve URL to file in main bundle`
    }

    @IBOutlet var pdfview: UIView!

    @IBAction func share(_ sender: UIButton) {
    }

    @IBAction func doAction2(_ sender: UIBarButtonItem) {
        document.presentOptionsMenu(from: view.bounds, in: view, animated: true)
    }

    override func viewWillAppear(_ animated: Bool) {
        //Here you are going to display your PdfController
        //PDFController that is seprate class you had created to show pdf file being opened
        //i.e

        //check which button was being selected
        switch ButtonSelected.Tag {
        case 0:
            var document: UIDocumentInteractionController = {
                let pdfView = PDFView(frame: UIScreen.main.bounds)

                let url = Bundle.main.url(forResource: "EN1", withExtension: "pdf")

                let vc = UIDocumentInteractionController(url: url!)
                pdfView.document = PDFDocument(url: url!)
                view.addSubview(pdfView)
                vc.delegate = self

                return vc
            }()
            //  document.presentPreview(animated: true)
            break
        case 1:
            //here control when you selected button with tag 0
            //here need to open pdf AR2
            //set Frame here all bounds

            var document: UIDocumentInteractionController = {
                let pdfView = PDFView(frame: UIScreen.main.bounds)

                let url = Bundle.main.url(forResource: "EN2", withExtension: "pdf")

                let vc = UIDocumentInteractionController(url: url!)
                pdfView.document = PDFDocument(url: url!)
                view.addSubview(pdfView)
                vc.delegate = self

                return vc
            }()
            break
        case 2:
            //here control when you selected button with tag 0
            //here need to open pdf AR2
            //set Frame here all bounds

            var document: UIDocumentInteractionController = {
                let pdfView = PDFView(frame: UIScreen.main.bounds)

                let url = Bundle.main.url(forResource: "EN3", withExtension: "pdf")

                let vc = UIDocumentInteractionController(url: url!)
                pdfView.document = PDFDocument(url: url!)
                view.addSubview(pdfView)
                vc.delegate = self

                return vc
            }()
            break
        default:
            //Error Case
            print("No tag Value Available")
        }
    }
}

@available(iOS 11.0, *)
extension PDFViewControllerEN: UIDocumentInteractionControllerDelegate {
    func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
        return self
    }
}

Answer

Mansi picture Mansi · Apr 24, 2018

I have tried and explained in detail about UIDocumentInteractionController. Refer this link if you want to check the details.

https://medium.com/if-let-swift-programming/managing-files-in-ios-dfcdfdc1f426

Code

extension ViewController {
    /// This function will set all the required properties, and then provide a preview for the document
    func share(url: URL) {
        documentInteractionController.url = url
        documentInteractionController.uti = url.typeIdentifier ?? "public.data, public.content"
        documentInteractionController.name = url.localizedName ?? url.lastPathComponent
        documentInteractionController.presentPreview(animated: true)
    }

    /// This function will store your document to some temporary URL and then provide sharing, copying, printing, saving options to the user
    func storeAndShare(withURLString: String) {
        guard let url = URL(string: withURLString) else { return }
        /// START YOUR ACTIVITY INDICATOR HERE
        URLSession.shared.dataTask(with: url) { data, response, error in
            guard let data = data, error == nil else { return }
            let tmpURL = FileManager.default.temporaryDirectory
                .appendingPathComponent(response?.suggestedFilename ?? "fileName.png")
            do {
                try data.write(to: tmpURL)
            } catch {
                print(error)
            }
            DispatchQueue.main.async {
                /// STOP YOUR ACTIVITY INDICATOR HERE
                self.share(url: tmpURL)
            }
            }.resume()
    }
}

extension ViewController: UIDocumentInteractionControllerDelegate {
    /// If presenting atop a navigation stack, provide the navigation controller in order to animate in a manner consistent with the rest of the platform
    func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
        guard let navVC = self.navigationController else {
            return self
        }
        return navVC
    }
}

extension URL {
    var typeIdentifier: String? {
        return (try? resourceValues(forKeys: [.typeIdentifierKey]))?.typeIdentifier
    }
    var localizedName: String? {
        return (try? resourceValues(forKeys: [.localizedNameKey]))?.localizedName
    }
}

Calling

@IBAction func showOptionsTapped(_ sender: UIButton) {
    /// Passing the remote URL of the file, to be stored and then opted with mutliple actions for the user to perform
    storeAndShare(withURLString: "https://images5.alphacoders.com/581/581655.jpg")
}

Note

https://www.bignerdranch.com/blog/working-with-the-files-app-in-ios-11/

Before your files can appear in the Files app, you must indicate that your app supports Open in Place and File Sharing Enabled. These options are configured using keys in your Info.plist file.

The first key is UIFileSharingEnabled, which enables iTunes sharing of files in your Documents folder.

The second key is LSSupportsOpeningDocumentsInPlace, which grants the local file provider access to files in your Documents folder.

Add these keys to your Info.plist and set their values to YES.