Подтвердить что ты не робот

Как проверить, не может ли UIDocumentInteractionController открыть документ из-за отсутствия внешнего приложения на iPad?

Я использую UIDocumentInteractionController для отображения popover menu "Open In...", чтобы пользователь мог открыть документ в другом приложении.

Метод presentOpenInMenuFromBarButtonItem:animated: возвращает NO в случае, если приложение не может открыть данный документ (меню не будет отображаться). Но мне уже слишком поздно ждать, пока не дойдешь. Я хотел бы отключить кнопку, инициирующую это открытие, если это невозможно, вместо того, чтобы возлагать надежды на пользователя, а затем сказать "извините, его невозможно открыть".

Можно ли запросить систему, чтобы узнать, есть ли хотя бы одно приложение, зарегистрированное для определенного типа документа? Я проверил canPreviewItem: в QLPreviewController, но кажется, что он не поддерживает те же типы документов, которые UIDocumentInteractionController могут обрабатывать.

4b9b3361

Ответ 1

[EDIT] Не работает для iOS 6.0 (см. комментарий)

Кажется, что cancelMenuAnimated (без анимации вообще) - это ключ:

-(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;
}

Он вернет YES, если хотя бы одно приложение сможет открыть файл, указанный url. По крайней мере, он работает в моем случае (файлы KMZ), тестирование с помощью/без Dropbox-приложения на iPhone iOS 4.3.
Фактически, он работает, даже если url не указывает на фактический файл (т.е. @ "Test.kmz" ), но я бы не полагался на него для всех типов файлов.

Ответ 2

Я придумал менее хакерский способ делать что-то, но есть ограничение, что вы можете только определить, есть ли совместимое приложение после того, как пользователь выбрал для открытия в приложении. Это позволит вам обеспечить тот же пользовательский интерфейс, что и приложение 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 для обнаружения успешного открытия.