Resolved NSFileManager copyItemAtPath Operation not permitted

Discussion in 'iOS Programming' started by Tex-Twil, Sep 24, 2013.

  1. Tex-Twil, Sep 24, 2013
    Last edited: Sep 25, 2013

    Tex-Twil macrumors 68020

    Tex-Twil

    Joined:
    May 28, 2008
    Location:
    Europe
    #1
    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
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
  3. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #3
    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.
     
  4. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #4
    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.
     
  5. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #5
    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.
     
  6. xArtx macrumors 6502a

    Joined:
    Mar 30, 2012
    #6
    I don't think you can write to, Create, or Delete the Documents/Inbox directory anyway.
     
  7. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #7
    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.
     
  8. xArtx, Sep 24, 2013
    Last edited: Sep 24, 2013

    xArtx macrumors 6502a

    Joined:
    Mar 30, 2012
    #8
    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.




     
  9. Tex-Twil thread starter macrumors 68020

    Tex-Twil

    Joined:
    May 28, 2008
    Location:
    Europe
    #9
  10. xArtx, Sep 25, 2013
    Last edited: Sep 25, 2013

    xArtx macrumors 6502a

    Joined:
    Mar 30, 2012
    #10
    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.
     
  11. Tex-Twil thread starter macrumors 68020

    Tex-Twil

    Joined:
    May 28, 2008
    Location:
    Europe
    #11
    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"
     
  12. xArtx macrumors 6502a

    Joined:
    Mar 30, 2012
    #12
    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).
     
  13. Tex-Twil thread starter macrumors 68020

    Tex-Twil

    Joined:
    May 28, 2008
    Location:
    Europe
    #13
    yep, that's what I did
     
  14. xArtx macrumors 6502a

    Joined:
    Mar 30, 2012
    #14
    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) ?

     
  15. Tex-Twil thread starter macrumors 68020

    Tex-Twil

    Joined:
    May 28, 2008
    Location:
    Europe
    #15
    I haven't tried. I'm registered my app to handle PDF docs and it works fine.
     

Share This Page