Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Tex-Twil

macrumors 68030
Original poster
May 28, 2008
2,501
15
Berlin
Hi,
during the startup of my app, I'm trying to copy some sample resources from the application bundle to the "Documents/Inbox" directory but for some reason it fails on a real device and works on the simulator.

Code:
-(void) copyTestDocuments {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsPath = paths[0];

    // CREATE THE "Inbox" folder
    NSFileManager *fileManager = [NSFileManager defaultManager];
    documentsPath = [documentsPath stringByAppendingString:@"/Inbox/"];
    if ([fileManager fileExistsAtPath:documentsPath] == NO) {
        NSLog(@"Creating directory %@",documentsPath);
        NSError *error;
        BOOL success = [fileManager createDirectoryAtPath:documentsPath withIntermediateDirectories:YES attributes:nil error:&error];
        if (!success) {
            NSLog(@"failed: %@", error);
        }
    }

    // copy the two PDFs
    NSArray * pdfArray = @[@"201.pdf", @"iOS_Security_May12.pdf"];
    for(NSString *pdfName in pdfArray) {
        NSString *txtPath = [documentsPath stringByAppendingPathComponent:pdfName];


        if ([fileManager fileExistsAtPath:txtPath] == NO) {
            NSLog(@"Copying test document %@", pdfName);
            NSString *sourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:pdfName];
            NSError *error;

            // this fails
            BOOL success = [fileManager copyItemAtPath:sourcePath toPath:txtPath error:&error];
            if (!success) {
                NSLog(@"failed: %@", [error localizedDescription]);
            }
        }
    }
}

The "copyItemAtPath:sourcePath" fails with a "The operation couldn’t be completed. Operation not permitted" error. What am I doing wrong ?

thanks for the help
 
Last edited:
What am I doing wrong ?
First, your code doesn't stop or return when it fails.

When an operation fails, such as creating a directory, you NSLog a message, but instead of returning you just continue as if the operation succeeded. This is poorly designed error handling.


Second, you should be using fileExistsAtPath:isDirectory: instead of fileExistsAtPath:.

The 2nd method only tells you whether something exists at the given path. It doesn't tell you what kind of file-system object it is. It only tells you one thing: does something exist. For example, if it's a plain file, you'll get YES but you won't be able to create a sub-file because a plain file isn't a directory. The 1st method tells you two things: does something exist, is it a directory.
 
Hi,
during the startup of my app, I'm trying to copy some sample resources from the application bundle to the "Documents/Inbox" directory but for some reason it fails on a real device and works on the simulator.

Code:
-(void) copyTestDocuments {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsPath = paths[0];

    // CREATE THE "Inbox" folder
    NSFileManager *fileManager = [NSFileManager defaultManager];
    documentsPath = [documentsPath stringByAppendingString:@"/Inbox/"];
    if ([fileManager fileExistsAtPath:documentsPath] == NO) {
        NSLog(@"Creating directory %@",documentsPath);
        NSError *error;
        BOOL success = [fileManager createDirectoryAtPath:documentsPath withIntermediateDirectories:YES attributes:nil error:&error];
        if (!success) {
            NSLog(@"failed: %@", error);
        }
    }

    // copy the two PDFs
    NSArray * pdfArray = @[@"201.pdf", @"iOS_Security_May12.pdf"];
    for(NSString *pdfName in pdfArray) {
        NSString *txtPath = [documentsPath stringByAppendingPathComponent:pdfName];


        if ([fileManager fileExistsAtPath:txtPath] == NO) {
            NSLog(@"Copying test document %@", pdfName);
            NSString *sourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:pdfName];
            NSError *error;

            // this fails
            BOOL success = [fileManager copyItemAtPath:sourcePath toPath:txtPath error:&error];
            if (!success) {
                NSLog(@"failed: %@", [error localizedDescription]);
            }
        }
    }
}

The "copyItemAtPath:sourcePath" fails with a "The operation couldn’t be completed. Operation not permitted" error. What am I doing wrong ?

thanks for the help

What chown33 said. Plus an additional item:

Don't use stringByAppendingString to build system paths. It's fragile and tends to create ill-formed paths in various edge cases. Instead, use the NSString methods for handling paths, e.g. stringByAppendingPathComponent.
 
You should use pathForResource:eek:fType: to get the path to a pdf file in your app's bundle, in most cases.

I think that copyItemAtPath:toPath: will fail if toPath exists.

Also, it seems that you're changing your documentsPath to point to Inbox, and then using that to generate txtPath, which is probably not what you want.

You need to do the usual debugging. Print out the paths that you're using and it should become clear.
 
I don't think you can write to, Create, or Delete the Documents/Inbox directory anyway.
 
Why can't you write to Documents/Inbox? It's just a folder. You can certainly move and copy from it. It seems likely from his code that this is test code. It wouldn't make sense to write to it in a normal app though.
 
edit,,,
looked it up:
"
Your app can read and delete files in this directory but cannot create new files or write to existing files. If the user tries to edit a file in this directory, your app must silently move it out of the directory before making any changes.

The contents of this directory are backed up by iTunes."

Additionally,
I don't think you can delete the folder, but have to cycle every file in it,
and I don' think you can write new files into it either.




Why can't you write to Documents/Inbox? It's just a folder. You can certainly move and copy from it. It seems likely from his code that this is test code. It wouldn't make sense to write to it in a normal app though.
 
Last edited:
At first launch, Documents/Inbox can't exist yet because the App has
not yet registered to receive any attachments.
You might be still seeing it on a device because another run of the App
has actually received email, or you actually were able to create it.

At first launch, you can instead load an example file from your bundle,
and subsequently on any other load until Documents/Inbox exists.

Also, what chown said... looks like your program might have been ready to go on
to do some crazy stuff if the file didn't exist.
 
Last edited:
My app has a little file manager included and I was using the Inbox as the root of it which is obviously wrong since files cannot be created there.

I now use a "MyDocuments" folder as a root and when app is launched with "application:handleOpenURL:", I copy that file from "Inbox" to "MyDocuments"
 
My app has a little file manager included and I was using the Inbox as the root of it which is obviously wrong since files cannot be created there.

I now use a "MyDocuments" folder as a root and when app is launched with "application:handleOpenURL:", I copy that file from "Inbox" to "MyDocuments"

I think you want to delete from Inbox after the copy because both can be backed up, and one copy is a duplicate.
You could check the copy was success as described above before deleting the
Inbox copy (while you have the correct path).
 
I think you want to delete from Inbox after the copy because both can be backed up, and one copy is a duplicate.
You could check the copy was success as described above before deleting the
Inbox copy (while you have the correct path).
yep, that's what I did
 
Great, you've called it resolved :)

Were you able to import any of the file types opened in email by image preview?
(ie. bmp, png, jpg) ?

I haven't tried. I'm registered my app to handle PDF docs and it works fine.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.