使用UIActivityViewController和UIActivityItemProvider分享PDF文件

14

我需要在iOS上分享/打开一些不同的文件,例如将图像共享到iCloud或PDF打开到iBooks。虽然有一些文本和图像的示例,但没有其他类型的示例...

我创建了自己的UIActivityItemProvider;这里是简化版本:

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

从类似下面的方式开始分享:

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)

我希望看到的是一个共享对话框,如下图:

enter image description here

但是我得到的却是:

enter image description here

有什么建议吗?


1
文档说,只提供NSData(仅限NSData)将触发对dataTypeIdentifierForActivityType的调用 - 但这不是真的。同时NSURL也会触发它。提供NSURL而不是NSData将显示大多数已安装的应用程序 - 除了“保存到iBooks”。 - coyer
4个回答

32

使用Swift 3在UIActivityViewController中分享PDF文件

我花了很多时间思考如何在从URL加载的UIWebView中分享PDF文件,例如"http://youPdfFile.pdf"。

经过几天的努力,我找到了我认为最合适的方法:

1)必须先将PDF保存在文件系统中。例如,在加载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) 阅读保存的文件,然后分享它。 这种方法对我在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") 
            } 
        } 

getDirectoryPath() 这个函数在哪里?我遇到了一个错误。 - Dhaval Umraliya
嗨@DhavalUmraliya,这个函数是这样的:func getDirectoryPath() -> String { let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) let documentsDirectory = paths[0] return documentsDirectory } - Gabriel Raffa
1
我只有在使用 UIActivityViewController(activityItems: [documentoPath!] 而不是 UIActivityViewController(activityItems: [documento!] 时才得到了正确的文件名。 - Arjan

14

现有的答案演示了如何使用本地文件的URL来共享PDF。但是如果您不想创建文件,则可以使用您的PDF文件的Data表示形式。

假设您正在使用PDFKit在UI中显示PDF文件。这意味着您将处理PDFKit.PDFDocument类,该类具有dataRepresentation()方法。此方法返回Data,可以传递给UIActivityViewController初始化器。


9

在UIActivityViewController中,对于支持pdf的应用程序选项,您必须传递pdf文件的url

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)
    }
}

5

这段代码适用于我共享文件。当然,文件必须已经被创建:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.pdf", @"FileName"]];
NSURL *URL = [NSURL fileURLWithPath:fullPath];
NSArray *activityItems = [NSArray arrayWithObjects:URL, nil];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil];

[self presentViewController:activityViewController animated:YES completion:nil];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接