Как проверить, не может ли UIDocumentInteractionController открыть документ из-за отсутствия внешнего приложения на iPad?
Я использую UIDocumentInteractionController
для отображения popover menu "Open In...", чтобы пользователь мог открыть документ в другом приложении.
Метод presentOpenInMenuFromBarButtonItem:animated:
возвращает NO
в случае, если приложение не может открыть данный документ (меню не будет отображаться). Но мне уже слишком поздно ждать, пока не дойдешь. Я хотел бы отключить кнопку, инициирующую это открытие, если это невозможно, вместо того, чтобы возлагать надежды на пользователя, а затем сказать "извините, его невозможно открыть".
Можно ли запросить систему, чтобы узнать, есть ли хотя бы одно приложение, зарегистрированное для определенного типа документа? Я проверил canPreviewItem:
в QLPreviewController
, но кажется, что он не поддерживает те же типы документов, которые UIDocumentInteractionController
могут обрабатывать.
Ответы
Ответ 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
для обнаружения успешного открытия.
Ответ 5
-[UIApplication canOpenURL:]
должен выполнить эту работу.