Iphone 如何检查UIDocumentInteractionController是否因iPad上缺少外部应用程序而无法打开文档?

Iphone 如何检查UIDocumentInteractionController是否因iPad上缺少外部应用程序而无法打开文档?,iphone,objective-c,ipad,Iphone,Objective C,Ipad,我正在使用UIDocumentInteractionController显示弹出菜单“在…中打开”,以便用户可以在其他应用程序中打开文档 方法presentOpenMinumfromBarbuttonItem:animated:在没有应用程序能够打开给定文档的情况下返回NO(菜单将不显示)。但是我已经太晚了,不能等到现在。如果无法打开,我想禁用启动该打开的按钮,而不是提高用户的期望,然后说“对不起,无法打开” 是否可以查询系统以查看是否至少有一个应用程序注册了特定的文档类型?我已经在QLPrev

我正在使用
UIDocumentInteractionController
显示弹出菜单“在…中打开”,以便用户可以在其他应用程序中打开文档

方法
presentOpenMinumfromBarbuttonItem:animated:
在没有应用程序能够打开给定文档的情况下返回
NO
(菜单将不显示)。但是我已经太晚了,不能等到现在。如果无法打开,我想禁用启动该打开的按钮,而不是提高用户的期望,然后说“对不起,无法打开”


是否可以查询系统以查看是否至少有一个应用程序注册了特定的文档类型?我已经在
QLPreviewController
中选中了
canPreviewItem:
,但它似乎不支持
UIDocumentInteractionController
可以处理的相同文档类型

应该做这项工作。

[EDIT]不适用于iOS 6.0(请参阅评论)

DismissMenuAnimate(完全没有动画)似乎是关键:

-(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;
}
如果至少有一个应用程序能够打开url指向的文件,它将返回YES。 至少它在我的案例(KMZ文件)中有效,在iPhone iOS 4.3上使用/不使用Dropbox应用程序进行测试。

实际上,即使url不指向实际文件(即@“test.kmz”),它似乎也能工作,但我不会对所有文件类型都依赖它。

我想出了一种不太老练的方法,但有一个限制,即只有在用户选择在某个应用中打开后,才能检测是否有兼容的应用。这将使您能够提供与Dropbox应用程序相同的用户体验

您只需设置
UIDocumentInteractionControllerDelegate
,并创建一个布尔标志属性,用于保存是否显示菜单

在界面中:

/**
 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;
在实施过程中:

- (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];
}
我希望这能帮助一些人。

这对我很有用:

   self.docController = [UIDocumentInteractionController interactionControllerWithURL:url];
   UIView *v = [[UIView alloc] init];
   BOOL isAnAppAvalaible = [self.docController presentOpenInMenuFromRect:CGRectZero inView:v animated:NO];

如果使用
PresentPreviewInimated:
显示文件,则可以使用
openResult
检测文件是否已成功打开。

似乎canOpenURL只解析URL的方案。在这种情况下,我总是使用file://并且我想检查不同的文档类型(pdf、jpeg等)。在任何情况下,canOpenURL:确定您的应用程序是否可以打开文档,而不是您安装的其他应用程序是否可以打开文档?呃,我们知道我们正在编写的程序可以打开哪些文件,对吗?因为是我们在写应用程序
canOpenURL:
确定是否有其他应用程序可以打开该方案,请参阅上面链接的官方文档中的注释。在OS X上,此功能位于
NSWorkspace
中,它与
NSApplication
分开。但不知何故,苹果决定在iOS上将它们结合起来。奇怪。这是我以前采用的解决方案,但对iOS 6来说是一个警告。以这种方式呈现和解除控制器似乎会对UITabBar产生一些副作用,具体来说,组成选项卡栏的“UITabbutton”(专用API)是隐藏的,但不是未隐藏的。通过一点挖掘,似乎按钮被设置为0 alpha,然后在调用“present”方法时隐藏在动画完成块中。不幸的是,动画完成块是在调用“discouse”方法后执行的,因此按钮保持隐藏状态。这个问题的解决方案是什么?我遇到了与@Weaverfish相同的问题,所以我所做的是在窗口中而不是视图中显示<代码>[docController presentoptions menufromrect:window.bounds-inView:window-animated:NO]
UIView*v=[[UIView alloc]init]
canOpen=[docController presentopenmenufromrect:CGRectZero-inView:v-animated:NO]这看起来像一个巧妙的把戏。不幸的是,如果你安装了DropBox或OneDrive,他们会声称可以打开任何东西。您现在还可以向Notes添加任何内容。PresentPreviewInMated:始终为我返回否。我将坚持使用PresentOpenMinumeFromRect:inView:animated:在视图中显示的位置将其移出屏幕。
NSURL *url = [NSURL URLWithString:@"path_to_the_file"];
UIDocumentInteractionController *controller =
    [UIDocumentInteractionController interactionControllerWithURL:url];
BOOL openResult = [controller presentPreviewAnimated:NO];