Reputation: 372
I am using UIDocumentInteractionController
for showing popover menu "Open In..." so that user can open a document in other application.
Method presentOpenInMenuFromBarButtonItem:animated:
returns NO
in case there is no application able to open given document (menu will not show). But it is too late for me to wait until getting so far. I would like to disable the button initiating that opening if it is not possible instead of raising expectations of an user and then say "sorry, it is not possible to open it".
Is it possible to query system to see if there is at least one application registered for particular document type? I have checked canPreviewItem:
in QLPreviewController
, but it seems it doesn't support the same document types which UIDocumentInteractionController
can handle.
Upvotes: 19
Views: 13166
Reputation: 3773
NSURL *url = [NSURL URLWithString:@"path_to_the_file"];
UIDocumentInteractionController *controller =
[UIDocumentInteractionController interactionControllerWithURL:url];
BOOL openResult = [controller presentPreviewAnimated:NO];
If you use presentPreviewAnimated:
for showing files you can use openResult
to detect if it was opened successfully.
Upvotes: 1
Reputation: 1348
This works for me:
self.docController = [UIDocumentInteractionController interactionControllerWithURL:url];
UIView *v = [[UIView alloc] init];
BOOL isAnAppAvalaible = [self.docController presentOpenInMenuFromRect:CGRectZero inView:v animated:NO];
Upvotes: 3
Reputation: 2418
I came up with a less hacky way of doing things, but there is a limitation that you can only detect whether there's a compatible app after the user has selected to open in an app. This will enable you to provide the same user experience as the Dropbox app.
All you need to do is set up the UIDocumentInteractionControllerDelegate
and create a boolean flag property that holds whether or not the menu was presented.
In the interface:
/**
The document interaction controller used to present the 'Open with' dialogue.
*/
@property (nonatomic,strong) UIDocumentInteractionController *documentInteractionController;
/**
Boolen that holds whether or not there are apps installed that can open the URL.
*/
@property (nonatomic) BOOL hasCompatibleApps;
In the implementation:
- (void)shareFileAtURL:(NSURL*)fileURL
{
[self setDocumentInteractionController:[UIDocumentInteractionController interactionControllerWithURL:fileURL]];
[[self documentInteractionController] setDelegate:self];
[self setHasCompatibleApps:NO];
[[self documentInteractionController] presentOpenInMenuFromRect:[self popoverRect] inView:[self popoverView] animated:YES];
if (![self hasCompatibleApps])
{
// Show an error message to the user.
}
}
#pragma mark - UIDocumentInteractionControllerDelegate methods
- (void)documentInteractionControllerWillPresentOpenInMenu:(UIDocumentInteractionController *)controller
{
[self setHasCompatibleApps:YES];
}
I hope that helps some people.
Upvotes: 5
Reputation: 2286
[EDIT] Not working for iOS 6.0 (see comment)
It seems that dismissMenuAnimated (with no animation at all) is the key:
-(BOOL)canOpenDocumentWithURL:(NSURL*)url inView:(UIView*)view {
BOOL canOpen = NO;
UIDocumentInteractionController* docController = [UIDocumentInteractionController
interactionControllerWithURL:url];
if (docController)
{
docController.delegate = self;
canOpen = [docController presentOpenInMenuFromRect:CGRectZero
inView:self.view animated:NO];
[docController dismissMenuAnimated:NO];
}
return canOpen;
}
It will return YES if at least one application is able to open the file pointed by url.
At least it's working in my case (KMZ files), testing with/without Dropbox app on iPhone iOS 4.3.
Actually, it seems to work even if url is not pointing to an actual file (i.e. @"test.kmz"), but I wouldn't rely on it for all file types.
Upvotes: 11