UIDocumentInteractionController stops working with iOS 8

I have a PDF file saved in a document directory. The file path is stored in the NSString property "self.URL". Here is my code for representing activity items:

-(void)presentDocumentInteractionController{ self.docController = [UIDocumentInteractionController interactionControllerWithURL:self.URL]; self.docController.delegate = self; [_docController setUTI:@"com.adobe.pdf"]; [_docController presentOptionsMenuFromBarButtonItem:self.activityBarButton animated:YES]; } 

Before iOS 8, this code worked fine. The user was presented with a list of items such as print, copy, and email to choose from. After upgrading to iOS 8 / Xcode 6, I get this runtime error (this does not crash the application):

 Unknown activity items supplied: ( "<UITextViewPrintFormatter: 0x7f908ba53ca0>" ) 

How can I solve this problem?

+5
source share
3 answers

I have the same problem and I switched to using UIActivityViewController . However, this makes applications that can open PDFs no longer display, so maybe this is not what you want.

Minimum Solution:

If you want to do the minimal work, you don’t even need to read the PDF file in NSData , use NSURL as an activity element, and iOS seems to know what to do:

 - (void)share:(id)sender { UIActivityViewController *activity = [[UIActivityViewController alloc] initWithActivityItems:@[self.URL] applicationActivities:nil]; if ([activity respondsToSelector:@selector(popoverPresentationController)]) { activity.popoverPresentationController.barButtonItem = <# BAR BUTTON ITEM #>; } [self presentViewController:activity animated:YES completion:NULL]; } 

Original answer:

Make your view controller bound to the UIActivityItemSource protocol, then you can do:

 - (void)share:(id)sender { self.pdfData = [NSData dataWithContentsOfURL:self.URL]; UIActivityViewController *activity = [[UIActivityViewController alloc] initWithActivityItems:@[self] applicationActivities:nil]; if ([activity respondsToSelector:@selector(popoverPresentationController)]) { activity.popoverPresentationController.barButtonItem = <# BAR BUTTON ITEM #>; } [self presentViewController:activity animated:YES completion:NULL]; } 

Adhering to the protocol, if you have a PDF file, this is relatively simple. You can, of course, optimize and return smaller NSData and even a preview image, but minimally do this:

 - (id)activityViewControllerPlaceholderItem:(UIActivityViewController *)activityViewController { return _pdfData; } - (id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType { return _pdfData; } - (NSString *)activityViewController:(UIActivityViewController *)activityViewController subjectForActivityType:(NSString *)activityType { return self.title; } - (NSString *)activityViewController:(UIActivityViewController *)activityViewController dataTypeIdentifierForActivityType:(NSString *)activityType { return @"com.adobe.pdf"; } 
+5
source

This solved the problem for me:

ObjC:

 dispatch_async(dispatch_get_main_queue(), ^() { [_docController presentOptionsMenuFromRect:button.bounds inView:button animated:YES]; }); 

Swift:

 if let docController = UIDocumentInteractionController(URL: url) { dispatch_async(dispatch_get_main_queue()) { docController.presentPreviewAnimated(true) } } else { // handle nil docController } 

I do not use swift, so this code may not work.

0
source

Use

 - (BOOL)presentOpenInMenuFromBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated; 

Instead

 - (BOOL)presentOptionsMenuFromBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated; 
0
source

All Articles