UIDocumentInteractionController not showing print option
Asked Answered
D

2

7

I have code to show a document as follows:

documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:self.thisUrl];

NSString *pathExtension = [self.thisUrl pathExtension];
if (pathExtension) {
    NSString *UTI = (__bridge NSString*)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)(pathExtension), NULL);
    if (UTI) {
        documentInteractionController.UTI = UTI;
    }
}
documentInteractionController.delegate = self;
[documentInteractionController presentOptionsMenuFromBarButtonItem:shareButton animated:YES];

When the options menu is displayed, it shows a list of apps that can open the document (e.g. Message), along with a list of actions below.

The options menu shows a list actions that is different from the menu shown in e.g., the Mail app.

The main difference is that the Mail app shows a "print" option, while my options menu does not. How do I get the options menu to show the print option?

The options menu shown in my app

The options menu shown in Mail

EDIT: I did a further test where I implemented the methods:

- (BOOL)documentInteractionController:(UIDocumentInteractionController *)controller canPerformAction:(SEL)action
{
  return YES;
}

- (BOOL)documentInteractionController:(UIDocumentInteractionController *)controller performAction:(SEL)action
{
  return YES; // or NO, doesn't matter
}

This had the effect of showing the "print", "copy" and "save to camera roll" actions in the popup view. Nothing happened when I tapped them, probably because I didn't properly implement -performAction. I also get a warning in the console log about using legacy methods.

This was a step backwards in some ways because I could no longer print some documents which were able to print correctly with the document interaction controller before I added those methods.

Declare answered 2/6, 2015 at 5:13 Comment(11)
Have you tried implementing -documentInteractionController:canPerformAction: on your delegate and returning YES for print:? The method is deprecated because Apple wants people to use UIActivityViewController as of iOS 7, which you're not. Assuming Apple does, that might also explain the difference.Leid
I don't want to use a deprecated method though, it will just result in getting rejected at some point in the future.Declare
I was originally using activity view controller, but it doesn't show the "open in" options that the document interaction controller hasDeclare
I'm not aware of Apple rejecting for use of a deprecated method but it does sound exactly like something they would do. But have you tried implementing that method merely as a diagnostic?Leid
That's what deprecated generally means, after a while they will start rejecting appsDeclare
If you think that's the most important topic then, no, deprecated doesn't mean that. E.g. objc_setSuperclass was introduced in iOS 2.0, deprecated in iOS 2.0 and remains available and usable without rejection as of iOS 8. If you run the diagnostic test then let us know your findings.Leid
Sure ok I added that method. It then added the print option but broke the print button for some other documents that were working correctly before. I don't really see the point because I'm not willing to use a deprecated method anyway.Declare
You've surely have missed the point of what deprecated meansBlueberry
@Lefteris, I'll concede that point, but I don't think my decision to not use deprecated methods is a wrong oneDeclare
This depends on the minimum OS version that you plan to support...Blueberry
Have you tried NOT setting UTI and NOT setting the delegate property? I use presentOptionsMenuFromRect:inView:animated: without these two and on a PDF file and generally get the options I want, including copy and print, although not "save to camera roll". The latter might make sense as a PDF cannot be saved directly to the camera roll anyway.Fielder
F
2

Apple encourage you to use UIActivityViewController. You can easily achieve this with that. However Print option is available only if your sharing content type supports printing. You can see a list of supported activities by data types here

- (IBAction)shareButton:(UIBarButtonItem *)sender
{
    NSString *textToShare = @"Text to share";
    NSURL *myWebContent = [NSURL URLWithString:@"http://yourpath.com/yourfile.pdf"]; // set your printable file here!

NSData *myData = [NSData dataWithContentsOfURL:myWebContent];


    NSArray *objectsToShare = @[textToShare, myData];

    UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:objectsToShare applicationActivities:nil];

//Add exclusions here
    NSArray *excludeActivities = @[UIActivityTypeAirDrop,
                                   UIActivityTypeAssignToContact,
                                   UIActivityTypeSaveToCameraRoll,
                                   UIActivityTypeAddToReadingList,
                                   UIActivityTypePostToFlickr,
                                   UIActivityTypePostToVimeo];

    activityVC.excludedActivityTypes = excludeActivities;

    [self presentViewController:activityVC animated:YES completion:nil];
}
Fascinator answered 8/6, 2015 at 11:0 Comment(1)
I was originally using the activity view controller, but this wouldn't show many of the "Open in" options that the document UI controller shows. What I wanted was something much like the sharing menu view that the mail app had. I think I've got a working solution using the QLPreviewController, if I get it workng to my satisfaction I'll post that as an answerDeclare
D
2

I got this working using the QuickLook framework. I don't know why the "print" option sometimes doesn't appear for the document interaction controller, but then again, apparantly noone else does either.

The QuickLook framework supports previewing some document types but not all, so I left in my previous view controller and the document interaction controller for those unsupported types.

Below is a snippet of my working code.

@interface PreviewItemDataSource ()
@property (nonatomic, retain) NSURL* item;
@end

@implementation PreviewItemDataSource

@synthesize item=_item;

+(PreviewItemDataSource*)dataSourceWithItem:(NSURL*)item
{
    PreviewItemDataSource *source = [[PreviewItemDataSource alloc] init];
    source.item = item;
    return source;
}

-(NSInteger) numberOfPreviewItemsInPreviewController:(QLPreviewController*)controller {
    return 1;
}

- (id<QLPreviewItem>) previewController:(QLPreviewController*)controller previewItemAtIndex:(NSInteger)index {
    return self.item;
}

@end

@interface AppDelegate ()
@property (nonatomic, retain) PreviewItemDataSource *dataSource;
@end

...

-(void) openExternalFile:(NSString*) filePath withDelegate:(id<ChildBrowserDelegate>)delegate
{
    if ([filePath length] == 0)
        return;

    NSURL *item = [NSURL URLWithString:filePath];
    if (item && [QLPreviewController canPreviewItem:item]) {
        [self openQuickLookForItem:item];
    } else {
        // previous method unchanged
    }
}

- (void) openQuickLookForItem:(NSURL*)item {
    QLPreviewController *controller = [[QLPreviewController alloc] init];
    PreviewItemDataSource *dataSource = [PreviewItemDataSource dataSourceWithItem:item];
    controller.dataSource = dataSource;
    controller.modalPresentationStyle = UIModalPresentationFullScreen;
    [controller setCurrentPreviewItemIndex:0];

    [self.viewController presentViewController:controller animated:YES completion:nil];

    self.dataSource = dataSource;
}
Declare answered 9/6, 2015 at 1:33 Comment(1)
The 250 bounty is still available if anyone can actually answer the question of why the print option doesn't appear for the document interaction controller, but for now this solution is what I went with.Declare

© 2022 - 2024 — McMap. All rights reserved.