我想拦截来自UIDocumentInteractionController的任何支持的文件类型的点击,并在模态视图中显示它们(由presentPreviewAnimated:
UIDocumentInteractionController 的方法提供).此模态视图还提供"Open In ..."功能,以在设备上的其他兼容应用程序中打开任何这些文档.下面的代码将拦截这些点击,检测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文档特别提到了文档控制器需要手动保留的事实,所以我这样做了.我也需要被释放,所以我这样做,如果没有使用控制器(顶级方法)并试图在它使用后释放它(委托方法),但该版本导致崩溃,所以我删除它,看起来似乎从这个角度来看工作正常.
有了背景,我的问题与这样的事实有关,虽然这个代码似乎在iPhone模拟器中工作(在线文档在presentPreviewAnimated:
视图中正确显示,但没有'Open In ...'对话框不能在sim)中使用,它不会显示presentPreviewMethod:
在iPad上的SIM卡或我的实际iPhone或iPad设备上.我相信正确调用该presentPreviewAnimated:
方法,但该方法返回NO
,这意味着它无法显示文档预览.
为什么会这样?我没有正确保存文件(因此它没有被检测为*pdf或*doc等)?还有什么我可能做错了?除了Apple文档之外,还有很少的文档或示例代码,所以我希望至少这个代码对某些人有帮助,尽管我希望它首先100%工作.提前致谢.