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

Posted

技术标签:

【中文标题】如何检查 UIDocumentInteractionController 是不是由于 iPad 上缺少外部应用程序而无法打开文档?【英文标题】:How to check if UIDocumentInteractionController will fail to open document due to missing external application on iPad?如何检查 UIDocumentInteractionController 是否由于 iPad 上缺少外部应用程序而无法打开文档? 【发布时间】:2011-02-10 13:58:25 【问题描述】:

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

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

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

【问题讨论】:

【参考方案1】:

[编辑] 不适用于 iOS 6.0(见评论)

看来dismissMenuAnimated(根本没有动画)是关键:

-(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”),它似乎也可以工作,但我不会依赖它来处理所有文件类型。

【讨论】:

这是我之前采用的解决方案,但对 iOS 6 提出警告。似乎以这种方式呈现和关闭控制器会对 UITabBar 产生一些副作用 - 特别是 'UITabBarButton's (private API)构成标签栏是隐藏的,但不是未隐藏的。从一点挖掘看来,按钮设置为 0 alpha,然后在调用“present”方法时隐藏在动画完成块中。不幸的是,动画完成块是在调用 'dismiss' 方法之后执行的,所以按钮仍然隐藏。 这个问题的任何解决方案..? 我遇到了与@Weaverfish 相同的问题,所以我所做的是在窗口中而不是视图中呈现。 [docController presentOptionsMenuFromRect:window.bounds inView:window animated:NO]; UIView *v = [[UIView alloc] init]; canOpen = [docController presentOpenInMenuFromRect:CGRectZero inView:v animated:NO]; 这看起来很巧妙。不幸的是,如果您安装了 DropBox 或 OneDrive,他们声称可以打开任何东西。您现在还可以向 Notes 添加任何内容。【参考方案2】:

我想出了一个不那么 hacky 的做事方式,但是有一个限制,你只能在用户选择在应用中打开后才能检测是否有兼容的应用。这将使您能够提供与 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];

我希望这对某些人有所帮助。

【讨论】:

【参考方案3】:

这对我有用:

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

【讨论】:

【参考方案4】:
NSURL *url = [NSURL URLWithString:@"path_to_the_file"];
UIDocumentInteractionController *controller =
    [UIDocumentInteractionController interactionControllerWithURL:url];
BOOL openResult = [controller presentPreviewAnimated:NO];

如果您使用presentPreviewAnimated: 显示文件,您可以使用openResult 来检测是否打开成功。

【讨论】:

presentPreviewAnimated: 总是为我返回 NO。我将坚持使用 presentOpenInMenuFromRect:inView:animated: 它在移出屏幕的视图中呈现。【参考方案5】:

-[UIApplication canOpenURL:] 应该可以完成这项工作。

【讨论】:

似乎 canOpenURL 只解析 URL 的方案。在这种情况下,我总是使用 file:// 并且我想检查不同的文档类型(pdf、jpeg、...) 无论如何,does not canOpenURL: 确定您的应用程序是否可以打开文档,而不是您安装的其他应用程序是否可以打开文档? 呃,我们知道我们正在编写的程序可以打开哪些文件,对吧?因为是我们在编写应用程序? canOpenURL: 判断是否有其他应用程序可以打开方案,请参阅上面链接的官方文档中的评论。在 OS X 上,此功能位于 NSWorkspace 中,并且与 NSApplication 分开。但不知何故,Apple 决定将它们结合到 iOS 上。奇怪。

以上是关于如何检查 UIDocumentInteractionController 是不是由于 iPad 上缺少外部应用程序而无法打开文档?的主要内容,如果未能解决你的问题,请参考以下文章

如何检查元素是不是没有特定的类?

如何进行PYTHON语法检查

单击然后检查时如何设置字体真棒检查图标[关闭]

如何编写Windows安全检查脚本

如何检查网络关闭

如何检查 XmlAttributeCollection 中是不是存在属性?