Here I want to achieve a function which can copy a res file from main bundle (which is added manually from Mac Finder to Xcode project ) (Fig 1) to Document Folder.
Click here to see the Xcode project structure
And to achieve that goal, I use NSFileManager. Here is the function code:
- (void)addCamConfig { NSFileManager *fileManager = [NSFileManager defaultManager]; NSError *error; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *destPath = [documentsDirectory stringByAppendingPathComponent:CAM_CONFIG]; if (![fileManager fileExistsAtPath:destPath]) { NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"cam" ofType:@"yaml"]; BOOL ret = [fileManager copyItemAtPath:sourcePath toPath:destPath error:&error]; if (error) { NSLog(@"cam_ret:%d\nsourcePath:%@\ndestPath:%@\nerror:%@",ret,sourcePath,destPath,error.description); } } }
In that case, sourcePath and destPath are both ensured not to be nil.
But strange thing happened in the first time, "copyItemAtPath:sourcePath toPath:destPath error:&error" return "NO" and error log showed below:
cam_ret:0 sourcePath:/private/var/containers/Bundle/Application/3DF49723-E11D-4D67-AD0F-39C2B82B80A4/NitroDemo.app/cam.yaml destPath:/var/mobile/Containers/Data/Application/181F8B72-402B-4D0C-91D5-0D9759BC607E/Documents/nitro/cam.yaml error:Error Domain=NSCocoaErrorDomain Code=4 "The file “cam.yaml” doesn’t exist." UserInfo={NSSourceFilePathErrorKey=/private/var/containers/Bundle/Application/3DF49723-E11D-4D67-AD0F-39C2B82B80A4/NitroDemo.app/cam.yaml, NSUserStringVariant=( ), NSDestinationFilePath=/var/mobile/Containers/Data/Application/181F8B72-402B-4D0C-91D5-0D9759BC607E/Documents/nitro/cam.yaml, NSFilePath=/private/var/containers/Bundle/Application/3DF49723-E11D-4D67-AD0F-39C2B82B80A4/NitroDemo.app/cam.yaml, NSUnderlyingError=0x2826476f0 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
Surprisingly, when I run project second time, the error disappeared, "copyItemAtPath:sourcePath toPath:destPath error:&error" return "YES".
And if I remove this app from my iPhone, then rebuild the project , reinstall and run the app first time, the same error message appears again. And as I expected, when I run the project second time, the error disappeared.
So I wonder what exactly happened in the first time and second time?
====================
UPDATE: I solved this problem by creating an intermediate folder nitro.
The key point here is that, as you may not noticed in the log, the dest path XXX/Documents/nitro/cam.yaml contains a not existed intermediate folder nitro. So in the first time when I call copyItemAtPath:sourcePath toPath:destPath error:&error, it fails and may create that folder (just for my guess). As a result, when I run second time, the copyItemAtPath:sourcePath toPath:destPath error:&error returns YES.