2011-03-06 262 views
0

我最近开始使用iPhone文件系统,起初我在理解某些概念时遇到了一些麻烦,但我认为最终我让它们变得直线流畅。将文件复制到文档目录导致失败

我的问题是,我试图复制从邮件应用程序文件(或打开我的应用程序与文件类型我的应用程序支持的任何应用程序)通过实施application:openURL:sourceApplication:annotation:方法文档目录(NSDocumentDirectory),但我的应用程序似乎在执行此操作时失败。

我创建了一个BOOL与我的文件管理器在复制文件时返回的值([fileManager copyItenAtPath:filePath toPath:newFilePath error:&error];,其中newFilePath是我的文档目录),然后检查它,然后NSLog如果失败或成功,我总是失败。

在试图找出我的Documents目录发生了什么后,我启用了文件共享,而不是看到我复制的文件,我得到一个收件箱文件夹,并将该文件夹复制到桌面后,我看到我的文件在那里。这是为什么?我怎样才能得到我想要的结果?

我在苹果文档的某个地方看到,当UIDocumentInteractionController打开一个文件时,它将它复制到收件箱文件夹,但显然,我的应用程序不使用UIDocumentInteractionController

预先感谢您的帮助,非常感谢。


编辑从这里开始

这里是我的原代码:

//AppDelegate.m 
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication (NSString *)sourceApplication annotation:(id)annotation 
{ 
    rootFolder.fileURLFromLaunch = url; //Passing the URL on to aproperty on a different class 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"ApplicationDidOpenFile" object:nil]; // notifying that the URL was passed and a file was opened 
    return YES; 
} 

这是做与文件中的所有工作类:

//RootFolder.m 

- (void)copyFileIntoApp 
{ 

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 

    NSString *documentsPath = [paths objectAtIndex:0]; 

    NSString *filePath = [fileURLFromLaunch path]; 

    NSString *displayName = [filePath lastPathComponent]; 

    NSError *error = NULL; 

    NSString *finalFilePath = [NSString stringWithFormat:@"%@/%@", documentsPath, displayName]; 

if ([fileManager fileExistsAtPath:finalFilePath]) { 

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"File already exists!" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; 
    [alert show]; 
    [alert release]; 

} else { 

    BOOL success = [fileManager copyItemAtPath:filePath toPath:finalFilePath error:&error]; 
    if (success) { 

     NSLog(@"success"); 
     Document *document = (Document *) [NSEntityDescription insertNewObjectForEntityForName:@"Document" inManagedObjectContext:managedObjectContext]; 

     [document setFilename:displayName]; 

     [document setPath:finalFilePath]; 

     if (![managedObjectContext save:&error]) { 

      UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Please try again or restart the app" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; 
      [alert show]; 
      [alert release]; 
     } 

     [fileArray insertObject:document atIndex:0]; 

     NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0]; 

     [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
           withRowAnimation:UITableViewRowAnimationFade]; 
     [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES]; 

    } else { 
     NSLog(@"failure %@ ", [error localizedDescription]); 
    } 


} 

}

我希望这使事情更清楚。

+0

失败时会得到什么错误信息? – Jim 2011-03-06 16:02:11

+0

没什么,我只是创建了一个'if ... else'循环,其中如果'BOOL'结果'YES',我会执行'NSLog(@“success”);'如果结果为NO,我会执行'NSLog(@失败“);' – ArturoVM 2011-03-06 16:17:29

+1

你能用'[error localalizedDescription]'记录错误吗? – FreeAsInBeer 2011-03-06 16:20:22

回答

1

我得到一个收件箱文件夹,并在该文件夹复制到桌面我看到我的文件都在那里。这是为什么?我怎样才能得到我想要的结果?

由于您的应用程序是沙盒式,并且无法访问不在其自己的目录中的文件。当用户告诉iOS他想用特定应用程序打开文件时,iOS会将该文件复制到收件箱目录中。


发布完整代码application:openURL:sourceApplication:annotation:
你的“我正在做这个和那个”并不是很有帮助,因为这和那之间有一个缺陷。你用你的话说明的算法是正确的,但是在你的实现中显然存在一个错误。

所以请发布此方法的完整代码。


编辑:我测试了你的代码的相关部分,他们似乎工作。

我会检查fileManager不是零。这可以解释为什么你没有看到错误信息。

+0

好吧,基于你刚才所说的,我似乎从一个错误的角度来看待这个问题:我正在做的是试图复制文件直接从它在邮件应用程序中的位置,但现在你告诉打开文件的应用程序会在其收件箱文件夹中获得该文件的副本,我想我应该将该文件从收件箱文件夹移动到Documents目录中,对吗?无论哪种方式,我会发布我的代码。我会尽力以不同的方式处理,并发布我的发现。 – ArturoVM 2011-03-07 03:35:40

+0

我可以在评论中张贴大量代码,我会在OP中发布。 – ArturoVM 2011-03-07 03:36:12

+1

@Arturo代码在问题中更有用。我测试了你的代码,它适用于我。但是我必须做一些改变才能使它工作,所以这些可以隐藏一些错误。例如,我不得不创建一个本地的NSFileManager实例,因此请检查'fileManager'不是在你的代码中。也许你忘了在某个地方启动它。 – 2011-03-07 10:12:56

1

你是否在实例化时将你的错误设置为null?如果您没有指出NSError指向的内存不会为NULL,并且您的逻辑将被触发。

这样做:

NSError *error = NULL; 

不是这个:

NSError *error; 
+0

我将它初始化为零,我会用'NULL'尝试一下,看看会发生什么 – ArturoVM 2011-03-06 16:15:59