将文件复制到文档目录导致失败
我最近开始摆弄 iPhone 文件系统,一开始我在理解一些概念时遇到了一些困难,但我认为最终我把它们搞清楚了。
我的问题是,我尝试通过实现 application:openURL:sourceApplication:annotation:
方法从邮件应用程序(或使用我的应用程序支持的文件类型打开我的应用程序的任何应用程序)复制文件到文档目录(NSDocumentDirectory
),但我的应用程序在执行此操作时似乎失败了。
我使用文件管理器在复制文件时返回的值创建了一个 BOOL
([fileManager copyItenAtPath:filePath toPath:newFilePath error:&error];
其中 newFilePath 是我的Documents Directory),然后检查它,然后 NSLog 是否有失败或成功,我总是失败。
为了找出我的文档目录发生了什么,我启用了文件共享,但我没有看到我复制的文件,而是得到一个收件箱文件夹,将该文件夹复制到桌面后,我看到我的文件就在那里。为什么会出现这种行为?我怎样才能得到我想要的结果?
我在 Apple 文档中读到,当 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]);
}
}
}
我希望将事情设置得更清楚。
I recently started playing around with the iPhone file system, at first I had some trouble understanding some concepts but I think that in the end I got them straight and flowing.
My problem is that I am trying to copy a file from the mail app (or any app that opens my app with a file type my app supports) by implementing the application:openURL:sourceApplication:annotation:
method to the Documents Directory (NSDocumentDirectory
), but my app seems to fail when doing this.
I created a BOOL
with the value that my file manager returns when copying the file ([fileManager copyItenAtPath:filePath toPath:newFilePath error:&error];
where newFilePath is my Documents Directory) and then check against it, and then NSLog if there was failure or success, I always get failure.
In an attempt to find out what was going on with my Documents directory I enabled file sharing, and instead of seeing the file I copied, I get an Inbox folder, and upon copying that folder to the Desktop I see that my files are in there. Why is this behavior? How can I get the result that I want?
I read somewhere in Apple documentation that when UIDocumentInteractionController
opens a file it copies it to the Inbox folder, but obviously, my app does not make use of UIDocumentInteractionController
.
Thank you in advance, your help is very much appreciated.
EDIT STARTS HERE
Here is my original code:
//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;
}
This is the class that does all the work with the file:
//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]);
}
}
}
I hope that sets things more clearly.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
因为您的应用程序是沙盒的,无法访问不在其自己目录中的文件。当用户告诉 iOS 他想要使用特定应用程序打开文件时,iOS 会将文件复制到收件箱目录中。
贴出
application:openURL:sourceApplication:annotation:
的完整代码。你的“我正在做这做那”并没有多大帮助,因为这和那之间存在缺陷。您用文字解释的算法是正确的,但您的实现中显然存在错误。
所以请发布此方法的完整代码。
编辑:我测试了您代码的相关部分,它们似乎有效。
我会检查
fileManager
是否不为零。这可以解释为什么您没有看到错误消息。Because your app is sandboxed and does not have access to files that are not in its own directory. When the user tells iOS that he wants to open a file with a specific app iOS copies the file into the inbox directory.
Post the complete code of
application:openURL:sourceApplication:annotation:
.Your "I'm doing this and that" is not very helpful because there is a flaw between this and that. The algorithm you explained with your words is correct, but there is clearly a bug in your implementation.
So please post the full code of this method.
Edit: I tested the relevant parts of your code and they seem to work.
I would check that
fileManager
is not nil. That would explain why you don't see an error message.您是否在实例化时将错误设置为空?如果您不这样做,
NSError
指向的内存将不会为 NULL,并且您的逻辑将被触发。这样做:
不是这样:
Are you setting your error to null upon instantiation? If you don't the memory that the
NSError
points to will not be NULL, and your logic will be tripped.Do this:
NOT this: