将文件复制到文档目录导致失败

发布于 2024-10-20 16:39:12 字数 3269 浏览 3 评论 0原文

我最近开始摆弄 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

疾风者 2024-10-27 16:39:12

我得到一个收件箱文件夹,将该文件夹复制到桌面后,我看到我的文件就在那里。为什么会出现这种行为?我怎样才能得到我想要的结果?

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


贴出application:openURL:sourceApplication:annotation:的完整代码。
你的“我正在做这做那”并没有多大帮助,因为这和那之间存在缺陷。您用文字解释的算法是正确的,但您的实现中显然存在错误。

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


编辑:我测试了您代码的相关部分,它们似乎有效。

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

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?

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.

南风几经秋 2024-10-27 16:39:12

您是否在实例化时将错误设置为空?如果您不这样做,NSError 指向的内存将不会为 NULL,并且您的逻辑将被触发。

这样做:

NSError *error = NULL;

不是这样:

NSError *error;

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:

NSError *error = NULL;

NOT this:

NSError *error;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文