1

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.

4
  • You might want to make sure that a 'Copy Files Phase' is present in your project configuration, in the 'Build Phases' tab. Otherwise, the file will not be copied into your compiled application's bundle. Commented Jul 28, 2020 at 20:14
  • @LinChiSin This does not make sense - can you give more code e.g. show where / when you copy it. Commented Jul 29, 2020 at 1:02
  • @G.Morin YES, the res file is ensure to be copied in application bundle as you can see the source path is correct. And I already solved this problem as descripted in UPDATE. Thx! Commented Jul 29, 2020 at 2:27
  • @skaak problem solved. Please see the update. Commented Jul 29, 2020 at 2:27

1 Answer 1

0

Ok, based on the update you could solve it then by inserting something like below.

 [NSFileManager.defaultManager createDirectoryAtPath:newDir withIntermediateDirectories:YES attributes:nil error:NULL]; 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.