我想拦截来自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
}
Run Code Online (Sandbox Code Playgroud)
我还实现了以下委托方法来使用适当的视图,并在视图被解除后删除文件(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
}
Run Code Online (Sandbox Code Playgroud)
请注意,Apple文档特别提到了文档控制器需要手动保留的事实,所以我这样做了.我也需要被释放,所以我这样做,如果没有使用控制器(顶级方法)并试图在它使用后释放它(委托方法),但该版本导致崩溃,所以我删除它,看起来似乎从这个角度来看工作正常.
有了背景,我的问题与这样的事实有关,虽然这个代码似乎在iPhone模拟器中工作(在线文档在presentPreviewAnimated:
视图中正确显示,但没有'Open In ...'对话框不能在sim)中使用,它不会显示presentPreviewMethod:
在iPad上的SIM卡或我的实际iPhone或iPad设备上.我相信正确调用该presentPreviewAnimated:
方法,但该方法返回NO
,这意味着它无法显示文档预览.
为什么会这样?我没有正确保存文件(因此它没有被检测为*pdf或*doc等)?还有什么我可能做错了?除了Apple文档之外,还有很少的文档或示例代码,所以我希望至少这个代码对某些人有帮助,尽管我希望它首先100%工作.提前致谢.
小智 -1
在 dealloc 方法中你只需编写
- (void)dealloc {
[controller release];
controller = nil;
[super dealloc];
}
Run Code Online (Sandbox Code Playgroud)
认为它会工作欢呼!