tags:

views:

3879

answers:

3

Hi

I am trying to copy an mp3 file from my Resources folder to a folder inside "Documents" folder of the app. On the simulator this works fine. But when I run it on a device, copying the files gives me this error

Operation could not be completed. (Cocoa error 513.)

The source and destinations paths are fine but I still cannot copy the file. Any ideas? Where can I find out what the cocoa error code 513 means?

Thanks.

Here's the relevant source code

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];

    NSString *folderPath = [documentsDirectory stringByAppendingPathComponent:@"Files"];

    NSString *insPath = [NSString stringWithFormat:@"%@.mp3", fileName];
    NSString *srcPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:insPath];
    NSString *destPath = [folderPath stringByAppendingPathComponent:insPath];
    NSLog(@"Src: %@, Dest: %@", srcPath, destPath);

    NSError *err;
    [fileManager moveItemAtPath:srcPath toPath:destPath error:&err];

    NSLog(@"Err desc-%@", [err localizedDescription]);
    NSLog(@"Err reason-%@", [err localizedFailureReason]);

Before making a call to moveItemAtPath, I am also creating the directory "Files" and it returns a YES.

Here's the log results

Src: /var/mobile/Applications/512D7565-7EF7-4C13-A015-19EEC3F3B465/MyApp.app/MyFile.mp3, Dest: /var/mobile/Applications/512D7565-7EF7-4C13-A015-19EEC3F3B465/Documents/Files/MyFile.mp3

Err desc-Operation could not be completed. (Cocoa error 513.)
Err reason-(null)

A question

Is there a limit to the file size when copying data from resources to Documents folder? The file I am trying to copy is about 5MB. Could that be a reason?

+3  A: 

Are you sure you are getting the path to Documents folder correctly? The absolute path in the simulator is different than the absolute path on the device.

You should use the following to make sure you get the correct path to the Documents directory:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0];

The path for documentsDirectory on the the device would be something like:

/var/mobile/Applications/30B51836-D2DD-43AA-BCB4-9D4DADFED6A2/Documents

The path on the simulator would be something like:

/Volumes/Stuff/Users/johnDoe/Library/Application Support/iPhone Simulator/User/Applications/118086A0-FAAF-4CD4-9A0F-CD5E8D287270/Documents

You can read more on the File & Networking page on the dev site.

Michael Shnitzer
Thanks Michael. I am getting the correct path on the device. I know because I am accessing other files from the same folder as where I am trying to copy these files without a problem. I have gone through the files and n/w page before posting the question but couldn't find anything which would help me resolve the issue.
lostInTransit
+2  A: 

That's the NSFileWriteNoPermissionError:

http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Constants/Reference/reference.html

Somehow, you do have the wrong path and it's not letting you write there. You could also delete the app and try again, in case somehow your app documents directory was set to the wrong permissions...

I'd give us the line of code doing the copy, and print outs of each variable used in that line. Then we can see what the problem is.

Kendall Helmstetter Gelner
added the source code in the question. thanks
lostInTransit
A good start, looks OK so far - can you also add the log results (especially the src: dst: line)
Kendall Helmstetter Gelner
I had a similar problem, was debugging for an hour and delete and reinstall the app, as you suggested, solved my problem!. thanks.
nacho4d
+3  A: 

EDIT:

Just figured out an even simpler solution. Instead of moveItemAtPath:toPath:error:, just use copyItemAtPath:toPath:error: ... since we truly want to copy the file from the mainBundle and not move it. I should have thought of that sooner!

E.g.

[[NSFileManager defaultManager] copyItemAtPath:mainBundleFilePath 
                                        toPath:destPath 
                                         error:&err]

See my previous comments below about why this works.


I believe I have the answer to this question. I can say for sure that the issue is not the destination file path.

I was getting the same Cocoa error 513 (NSFileWriteNoPermissionError) with pretty much the exact same code:

[[NSFileManager defaultManager] moveItemAtPath:mainBundleFilePath 
                                        toPath:destPath 
                                         error:&err]

The problem appears to be that the file, coming from the mainBundle, doesn't have suitable permissions to be moved to another place. I'm not sure if this command, if executed, would actually move the file from the mainBundle or just copy it...but either way, the file manager doesn't seem to like the idea.

The solution is simple: just read the mainBundle file into an NSData object and then write the NSData to a new file. Note the destination file path is the same in both examples, which shows us that lostInTransit is correct in saying that his file path is OK.

For this example, then, the following code will work and not throw an error:

NSData *mainBundleFile = [NSData dataWithContentsOfFile:mainBundleFilePath];
[[NSFileManager defaultManager] createFileAtPath:destPath 
                                        contents:mainBundleFile 
                                      attributes:nil];

BTW, in my own code, instead of passing a nil for attributes:, I set up an NSDictionary with a NSFileModificationDate attribute. I also wrapped the createFileAtPath:contents:attributes in an error handing if-statement. In other words,

if (![[NSFileManager defaultManager] createFileAtPath:destPath 
                                             contents:mainBundleFile 
                                           attributes:myAttributes]) { 
 // handle error as necessary, etc...

}

It took me a while to figure all of this out, so hopefully this solution will be helpful to others.

larry
Thanks Larry. Been stuck over this one for too long!
lostInTransit
Maybe the original problem is that when you try to move the file, you ask the program to alter its resource bundle (by deleting it after copying). I don't think the resource bundle can be altered on an iPhone (but it can be on the Simulator).
nevan
Agreed - well summarized Nevan. The key part for me was realizing the NSFileWriteNoPermissionError was in regards to the source location (the resource bundle) and not the destination location. Also, in this situation the permission error prevents both parts of the move task - the copy AND the delete.
larry