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

时间:2011-02-10 13:58:26

标签: iphone objective-c ipad

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

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

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

5 个答案:

答案 0 :(得分:11)

[编辑]不适用于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”),它似乎也能正常工作,但我不会依赖它来处理所有文件类型。

答案 1 :(得分:5)

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

我希望能帮助一些人。

答案 2 :(得分:3)

这对我有用:

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

答案 3 :(得分:0)

Type tableType = typeof (incommingtableName); // table type
string idPropertyName = "ID"; // id property name
int myId = 42; // value for searching

// here we are building lambda expression dynamically. It will be like m => m.ID = 42;
ParameterExpression param = Expression.Parameter(tableType, "m"); 
MemberExpression idProperty = Expression.PropertyOrField(param, idPropertyName);
ConstantExpression constValue = Expression.Constant(myId);

BinaryExpression body = Expression.Equal(idProperty, constValue);

var lambda = Expression.Lambda(body, param);


// then we would need to get generic method. As SingleOrDefault is generic method, we are searching for it,
// and then construct it based on tableType parameter

// in my example i've used CodeFirst context, but it shouldn't matter
SupplyDepot.DAL.SupplyDepotContext context = new SupplyDepotContext();
var dbTable = context.Set(tableType);


// here we are getting SingleOrDefault<T>(Expression) method and making it as SingleOrDefault<tableType>(Expression)
var genericSingleOrDefaultMethod =
    typeof (Queryable).GetMethods().First(m => m.Name == "SingleOrDefault" && m.GetParameters().Length == 2);
var specificSingleOrDefault = genericSingleOrDefaultMethod.MakeGenericMethod(tableType);

// and finally we are exexuting it with constructed lambda
var result = specificSingleOrDefault.Invoke(null, new object[] { dbTable, lambda });

如果您使用NSURL *url = [NSURL URLWithString:@"path_to_the_file"]; UIDocumentInteractionController *controller = [UIDocumentInteractionController interactionControllerWithURL:url]; BOOL openResult = [controller presentPreviewAnimated:NO]; 来显示文件,则可以使用presentPreviewAnimated:来检测它是否已成功打开。

答案 4 :(得分:-4)

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