UIDocumentInteractionController перестал работать iOS 8

У меня есть файл PDF, сохраненный в каталоге документов. Путь к файлу хранится в свойстве NSString «self.URL». Вот мой код для представления элементов деятельности:

-(void)presentDocumentInteractionController{
    self.docController = [UIDocumentInteractionController interactionControllerWithURL:self.URL];
    self.docController.delegate = self;
    [_docController setUTI:@"com.adobe.pdf"];
    [_docController presentOptionsMenuFromBarButtonItem:self.activityBarButton animated:YES];
}

До iOS 8 этот код работал нормально. Пользователю был представлен список элементов, таких как печать, копирование и электронная почта, на выбор. После обновления до iOS 8/XCode 6 я получаю эту ошибку времени выполнения (это не приводит к сбою приложения):

Unknown activity items supplied: (
    "<UITextViewPrintFormatter: 0x7f908ba53ca0>"
)

Как я могу решить эту проблему?


person amirfl    schedule 23.09.2014    source источник
comment
Журнал self.URL. Что это?   -  person rmaddy    schedule 24.09.2014
comment
это: файл:///Users/me/Library/Developer/CoreSimulator/Devices/272C49D3-7D19-4F03-A171‌​-78A7EAE1B02D/data/Containers/Data/Application/F70A1223-EDE0-472E-B94D-0B33AE5370‌​AE /Documents/filename.PDF Файл существует по этому адресу. То же свойство URL используется для загрузки PDF-файла в веб-просмотр и работает там, но не для контроллера взаимодействия с документом.   -  person amirfl    schedule 24.09.2014
comment
используйте presentOpenInMenuFromBarButtonItem вместо presentOptionsMenuFromBarButtonItem   -  person Eugene Prokoshev    schedule 26.09.2014
comment
@EugeneProkoshev не имел значения для меня с той же проблемой, что и user1349768   -  person Will    schedule 21.10.2014
comment
как вы инициируете свой docController, он находится в файле .h? какие свойства вы используете для этого, может быть, ARC выпускает все, когда вы оставляете приложение в своем приложении для просмотра PDF? Я установил его в .h в интерфейсе UIDocumentInteractionController *docController; и @property (сильное, неатомарное), затем синтезируйте в файле .m, затем используйте только docController no self., no _ отлично работает   -  person Boris Gafurov    schedule 06.11.2014


Ответы (3)


У меня та же проблема, и я перешел на использование UIActivityViewController. Однако это приводит к тому, что приложения, способные открывать PDF-файлы, больше не отображаются, так что, возможно, это не то, что вам нужно.

Минимальное решение:

Если вы хотите выполнить минимальную работу, вам даже не нужно читать PDF-файл в NSData, используйте NSURL в качестве элемента действия, и iOS, похоже, знает, что делать:

- (void)share:(id)sender
{
    UIActivityViewController *activity =
        [[UIActivityViewController alloc] initWithActivityItems:@[self.URL]
                                          applicationActivities:nil];
    if ([activity respondsToSelector:@selector(popoverPresentationController)]) {
        activity.popoverPresentationController.barButtonItem = <# BAR BUTTON ITEM #>;
    }
    [self presentViewController:activity animated:YES completion:NULL];
}

Оригинальный ответ:

Сделайте так, чтобы ваш контроллер представления придерживался протокола UIActivityItemSource, тогда вы можете сделать:

- (void)share:(id)sender
{
    self.pdfData = [NSData dataWithContentsOfURL:self.URL];
    UIActivityViewController *activity = [[UIActivityViewController alloc] initWithActivityItems:@[self] applicationActivities:nil];
    if ([activity respondsToSelector:@selector(popoverPresentationController)]) {
        activity.popoverPresentationController.barButtonItem = <# BAR BUTTON ITEM #>;
    }
    [self presentViewController:activity animated:YES completion:NULL];
}

Придерживаться протокола, если у вас есть PDF-файл, относительно просто. Вы, конечно, можете оптимизировать и вернуть NSData меньшего размера и даже изображение для предварительного просмотра, но сделать это минимально:

- (id)activityViewControllerPlaceholderItem:(UIActivityViewController *)activityViewController
{
    return _pdfData;
}

- (id)activityViewController:(UIActivityViewController *)activityViewController
    itemForActivityType:(NSString *)activityType
{
    return _pdfData;
}

- (NSString *)activityViewController:(UIActivityViewController *)activityViewController
    subjectForActivityType:(NSString *)activityType
{
    return self.title;
}

- (NSString *)activityViewController:(UIActivityViewController *)activityViewController
    dataTypeIdentifierForActivityType:(NSString *)activityType
{
    return @"com.adobe.pdf";
}
person Pascal    schedule 28.09.2014

Использовать

- (BOOL)presentOpenInMenuFromBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated;

Вместо

- (BOOL)presentOptionsMenuFromBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated;
person Soul Clinic    schedule 01.11.2014

Это решило проблему для меня:

Объект:

dispatch_async(dispatch_get_main_queue(), ^() {
    [_docController presentOptionsMenuFromRect:button.bounds inView:button animated:YES];
});

Быстрый:

if let docController = UIDocumentInteractionController(URL: url) {
    dispatch_async(dispatch_get_main_queue()) {
         docController.presentPreviewAnimated(true)
    }
} else {
    // handle nil docController 
}

Я не использую Swift, поэтому этот код может не работать.

person Pacha    schedule 24.10.2014
comment
Пожалуйста, внимательно ознакомьтесь с meta.stackexchange.com/questions/104227/. Вы, кажется, отвечаете на одно и то же на несколько вопросов, что не совсем уместно. - person Luís Cruz; 24.10.2014
comment
Я не уверен, что ваше решение работает как есть для каждого вопроса, поэтому вам нужно убедиться, что ваше решение решает проблему каждого вопроса. Если это так, то правильно будет проголосовать за закрытие как дубликат. - person Luís Cruz; 24.10.2014
comment
Вы можете преобразовать это в быстрое? ^() нельзя использовать в Swift - person TomSawyer; 07.11.2014
comment
@TomSawyer, возможно, вы используете presentOpenInMenuFromBarButtonItem? я не заставляю его работать правильно - person alex; 11.09.2015