简体   繁体   中英

UIDocumentInteractionController stopped working iOS 8

I have a PDF file saved in the document directory. The path to the file is stored in a NSString property 'self.URL'. Here is my code to present the 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'm getting this runtime error (it doesnt crash the app):

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

How can I solve this problem?

I have the same problem and have switched to using UIActivityViewController . However this makes the apps capable of opening the PDF no longer show up, so maybe that's not what you want.

Minimal Solution:

If you want to do minimal work, you don't even need to read your PDF into NSData , use a NSURL as activity item 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 adhere 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 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";
}

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 don't use swift so this code might not work.

Use

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

Instead of

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM