Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of UIActivityViewController and UIActivityItemProvider to share PDF

Tags:

ios

swift

I need to share/open some different files under iOS e.g. an image to iCloud or an pdf to iBooks. There are several examples around for text and images but nothing for somewhat else...

I created my own UIActivityItemProvider; simplified version here:

class MyItemProvider: UIActivityItemProvider {

  override func item() -> AnyObject {
    self.placeholderItem
  }

  override func activityViewController(activityViewController: UIActivityViewController, dataTypeIdentifierForActivityType activityType: String?) -> String {
    return kUTTypePDF as String
  }

  func activityViewControllerPlaceholderItem(activityViewController: UIActivityViewController) -> AnyObject {
    return self.placeholderItem
  }
}

And start sharing with something like:

let myPDF = NSData(contentsOfURL: NSBundle.mainBundle().URLForResource("testpdf", withExtension: "pdf")) {
let activityVC = UIActivityViewController(activityItems: [MyItemProvider(placeHolder: myPDF)], applicationActivities: nil)
self.presentViewController(activityVC, animated: true, completion: nil)

I expect a sharedialog like:

enter image description here

But all I get is:

enter image description here

Any suggestions?

like image 209
coyer Avatar asked Jun 23 '16 11:06

coyer


3 Answers

**

Share a PDF with UIActivityViewController in Swift 3

**

I've spent a lot of time thinking ways to share a PDF file within UIWebView loaded from a URL, like "http://youPdfFile.pdf"

After a coupe of days, I've found what I think it's the most suitable way:

1) The PDF must first be saved in the file system. For example, this can be done after loading the UIWebView:

class yourViewController: UIViewController{
       var documentPathToLoad = "http://youPdfFile.pdf"
       ...

       func webViewDidFinishLoad(_ webView: UIWebView) { 
           if yourWebView.isLoading { 
               // still loading 
               return 
           } 

           //Save the pdf document to file system 
           savePdf() 
       }

       func savePdf(){    
           let fileManager = FileManager.default 
           let paths = (NSSearchPathForDirectoriesInDomain((.documentDirectory, .userDomainMask, true)[0] as NSString).appendingPathComponent("documento.pdf") 
           let pdfDoc = NSData(contentsOf:URL(string: documentPathToLoad)!) 
           fileManager.createFile(atPath: paths as String, contents: pdfDoc as Data?, attributes: nil) 
       } 
}

2) Read the saved file and then share it. This method works for me in Swift 3.0.1:

func loadPDFAndShare(){ 

           let fileManager = FileManager.default 
           let documentoPath = (self.getDirectoryPath() as NSString).appendingPathComponent("documento.pdf") 

           if fileManager.fileExists(atPath: documentoPath){              
                let documento = NSData(contentsOfFile: documentoPath) 
                let activityViewController: UIActivityViewController = UIActivityViewController(activityItems: [documento!], applicationActivities: nil) 
                activityViewController.popoverPresentationController?.sourceView=self.view 
                present(activityViewController, animated: true, completion: nil) 
            } 
            else { 
                print("document was not found") 
            } 
        } 
like image 137
Gabriel Raffa Avatar answered Nov 13 '22 13:11

Gabriel Raffa


The existing answers demonstrate how to share a PDF using a local file's URL. However you don't have to create a file if you don't want to. The alternative is to use Data representation of your PDF file.

Let's say your're using PDFKit to display PDFs in UI. It means that you would deal with PDFKit.PDFDocument class which has dataRepresentation() method. This method returns Data which can be passed to UIActivityViewController initialiser.

like image 44
Legonaftik Avatar answered Nov 13 '22 11:11

Legonaftik


You have to pass pdf file url for pdf supported applications' options in UIActivityViewController.

func btnTapped() {
    if let pdf = Bundle.main.url(forResource: "yourPdfFileName", withExtension: "pdf", subdirectory: nil, localization: nil)  {
        self.sharePdf(path: pdf)
    }
}    

func sharePdf(path:URL) {

    let fileManager = FileManager.default

    if fileManager.fileExists(atPath: path.path) {
        let activityViewController: UIActivityViewController = UIActivityViewController(activityItems: [path], applicationActivities: nil)
        activityViewController.popoverPresentationController?.sourceView = self.view
        self.present(activityViewController, animated: true, completion: nil)
    } else {
        print("document was not found")
        let alertController = UIAlertController(title: "Error", message: "Document was not found!", preferredStyle: .alert)
        let defaultAction = UIAlertAction.init(title: "ok", style: UIAlertAction.Style.default, handler: nil)
        alertController.addAction(defaultAction)
        UIViewController.hk_currentViewController()?.present(alertController, animated: true, completion: nil)
    }
}
like image 9
Mushrankhan Avatar answered Nov 13 '22 12:11

Mushrankhan