Я хотел бы перехватить щелчки в любом из поддерживаемых типов файлов 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 особо упоминается тот факт, что контроллер документов необходимо было сохранить вручную, поэтому я сделал это. Я также должен быть освобожден, поэтому я делаю это, если контроллер не использовался (метод top) и пытался освободить его после его использования (метод делегата), но этот выпуск вызывал сбои, поэтому я удалил его, и все кажется чтобы работать с этой точки зрения нормально.
С учетом фона, мой вопрос связан с тем фактом, что хотя этот код работает в симуляторе iPhone (онлайн-документ отображается правильно в представлении presentPreviewAnimated:
, но без 'Open In' ... », который не может быть использован в симе), он не показывает presentPreviewMethod:
на симке iPad или моих реальных устройствах iPhone или iPad. Я считаю, что метод вызывается правильно, но метод presentPreviewAnimated:
возвращает NO
, что означает, что он не смог отобразить предварительный просмотр документа.
С чего бы это? Я не сохраняю файл должным образом (и поэтому он не определяется как * pdf или * doc и т. Д.)? Что еще я могу делать не так? Существует очень мало документации или примеров кода, кроме документации Apple, поэтому я надеюсь, что по крайней мере этот код будет кому-то полезен, хотя я бы хотел, чтобы он работал на 100% в первую очередь. Заранее спасибо.