Я хотел бы перехватить клики с любого из поддерживаемых типов файлов UIDocumentInteractionController и отобразить их в виде модальности (при условии по presentPreviewAnimated:
методу UIDocumentInteractionController). Это модальное представление также предоставляет функцию "Открыть в...", чтобы открыть любой из этих документов в других совместимых приложениях на устройстве. Приведенный ниже код перехватит эти клики, определит, имеет ли строка URL какой-либо из соответствующих суффиксов, загружает эти данные, записывает их в каталог, читает их снова и, наконец, использует данные с помощью метода presentPreviewAnimated:
. Я должен сначала записать данные в файловую систему, потому что UIDocumentInteractionController требует локальные данные и не может использовать данные непосредственно из URL (насколько я читал).
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
ILog(@"URL loading for NavigationTypeLinkClicked: %@", request.URL.absoluteString);
if ([request.URL.absoluteString hasSuffix:@"pdf"] || [request.URL.absoluteString hasSuffix:@"doc"] || [request.URL.absoluteString hasSuffix:@"xls"] || [request.URL.absoluteString hasSuffix:@"ppt"] || [request.URL.absoluteString hasSuffix:@"rtf"] || [request.URL.absoluteString hasSuffix:@"key"] || [request.URL.absoluteString hasSuffix:@"numbers"] || [request.URL.absoluteString hasSuffix:@"pages"]) {
if (NSClassFromString(@"UIDocumentInteractionController")) {
NSArray *parts = [request.URL.absoluteString componentsSeparatedByString:@"/"];
self.previewDocumentFileName = [parts lastObject];
NSLog(@"The file name is %@", previewDocumentFileName);
// Get file online
NSData *fileOnline = [[NSData alloc] initWithContentsOfURL:request.URL];
// Write file to the Documents directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
if (!documentsDirectory) {NSLog(@"Documents directory not found!");}
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:previewDocumentFileName];
[fileOnline writeToFile:appFile atomically:YES];
NSLog(@"Resource file '%@' has been written to the Documents directory from online", previewDocumentFileName);
[fileOnline release];
// Get file again from Documents directory
NSURL *fileURL = [NSURL fileURLWithPath:appFile];
UIDocumentInteractionController* docController = [UIDocumentInteractionController interactionControllerWithURL:fileURL];
docController.delegate = self;
[docController retain];
BOOL result = [docController presentPreviewAnimated:YES];
if (!result) {
[docController release];
}
return NO;
}
}
}
// Do lots of other URL-detecting stuff here
}
Я также применяю следующие методы делегата для использования соответствующего представления и для удаления файла после отклонения представления (previewDocumentFileName
- переменная класса):
#pragma mark -
#pragma mark Document Interaction Controller Delegate Methods
- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller {
return self;
}
- (void)documentInteractionControllerDidEndPreview:(UIDocumentInteractionController *)controller {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:previewDocumentFileName];
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager removeItemAtPath:appFile error:NULL];
//[controller release]; // Release here was causing crashes
}
Обратите внимание, что в Apple Documentation упоминалось о том, что контроллер документа необходимо сохранить вручную, поэтому я сделал это. Я также должен быть выпущен, поэтому я делаю это, если контроллер не был использован (верхний метод) и попытался выпустить его после его использования (метод делегирования), но этот выпуск вызывал сбои, поэтому я удалил его, и все кажется чтобы работать с этой точки зрения.
В связи с этим мой вопрос связан с тем, что, хотя этот код работает в симуляторе iPhone (онлайн-документ отображается правильно в представлении presentPreviewAnimated:
, хотя без "Open In"...", который нельзя использовать в симе), он не показывает presentPreviewMethod:
на iPad sim или моих реальных устройствах iPhone или iPad. Я считаю, что метод вызывается правильно, но метод presentPreviewAnimated:
возвращает NO
, что означает, что он не смог отобразить предварительный просмотр документа.
Зачем это было? Я не сохраняю файл должным образом (и, следовательно, он не обнаруживается как * pdf или * doc и т.д.)? Что еще я мог делать неправильно? Существует очень мало документации или пример кода, кроме Apple Documentation, поэтому я надеюсь, что по крайней мере этот код будет полезен кому-то, хотя я бы хотел, чтобы он работал на 100% первым. Спасибо заранее.