3

I am trying to copy a folder in my NSBundle which contains quite a number of images.
I tried doing it with these codes.

    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory,
                                                         NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *documentDBFolderPath = [documentsDirectory stringByAppendingPathComponent:@"Images"];

    NSString *resourceDBFolderPath = [[[NSBundle mainBundle] resourcePath]
                                          stringByAppendingPathComponent:@"Images"];
        [fileManager copyItemAtPath:resourceDBFolderPath toPath:documentDBFolderPath error:&error];

Lets say there's an image in the folder named Test.png and i want to display the image on my button, it does not work!
However, if i only copied a single image from the NSBundle to NSDocumentDirectory, it works!

Example:

Changing

stringByAppendingPathComponent:@"Images"  

To

stringByAppendingPathComponent:@"Test.png"

So the problem lies with copying the folder to NSDocumentDirectory!
Are my codes above incorrect?
Or it is impossible to copy folders? (Which means i have to copy files individually)

Lloydworth
  • 743
  • 6
  • 20
  • 38

3 Answers3

6

The code below will create a folder called "images" under document directory and copy all files from a folder called "folderinbundle" in your bundle to "images"

- (void) copyImages
{
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *sourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"folderinbundle"];  //folder contain images in your bundle
    NSString *destPath = [documentsDirectory stringByAppendingPathComponent:@"images"];  //images is your folder under document directory

    NSError *error;
    [[NSFileManager defaultManager] copyItemAtPath:sourcePath toPath:destPath error:&error];  //copy every files from sourcePath to destPath
}

Edit to clarify: The above will work if "folderinbundle" is a physical folder not a group.

user523234
  • 14,323
  • 10
  • 62
  • 102
5

Oscar is correct, there is currently no way to copy an entire folder with a single command.

A method such as this might do the trick (forewarning - my office connection is down and I can't access my Mac to verify this code is working. Will verify this once I am able). Simply call with [self copyDirectory:@"Images"] and it will handle the rest.

-(void) copyDirectory:(NSString *)directory {
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *documentDBFolderPath = [documentsDirectory stringByAppendingPathComponent:directory];
    NSString *resourceDBFolderPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:directory];

    if (![fileManager fileExistsAtPath:documentDBFolderPath]) {
        //Create Directory!
        [fileManager createDirectoryAtPath:documentDBFolderPath withIntermediateDirectories:NO attributes:nil error:&error];
    } else {
        NSLog(@"Directory exists! %@", documentDBFolderPath);
    }

    NSArray *fileList = [fileManager contentsOfDirectoryAtPath:resourceDBFolderPath error:&error];
    for (NSString *s in fileList) {
        NSString *newFilePath = [documentDBFolderPath stringByAppendingPathComponent:s];
        NSString *oldFilePath = [resourceDBFolderPath stringByAppendingPathComponent:s];
        if (![fileManager fileExistsAtPath:newFilePath]) {
            //File does not exist, copy it
            [fileManager copyItemAtPath:oldFilePath toPath:newFilePath error:&error];
        } else {
            NSLog(@"File exists: %@", newFilePath);
        }
    }
}

-- EDIT 11/9/2011 -- Sorry about that, as I forewarned I was not able to access my mac to verify the code. Updated the code and I have verified it is working properly now. Added a couple quick NSLogs to tell you if the new directory or the new file already exists.

Geekswordsman
  • 1,297
  • 8
  • 10
0

I am afraid there is currently no way to copy folders, and if there is a third party function that does it, all it will do really is copy file by file... Therefore you will have to copy each file individually.

Oscar Gomez
  • 18,436
  • 13
  • 85
  • 118
  • Oh no... Which means if i have 50 files to copy, i need to write the codes to copy for 50 of them? :( – Lloydworth Nov 09 '11 at 02:56
  • I'm afraid so. It looks like its either geekswordsman's code or a foreachloop of an array of file names. – CodaFi Nov 09 '11 at 03:55