Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy Folder (w/contents) from bundle to Documents directory - iOS

EDIT: SOLVED

Thanks Brooks. Your question led me to keep digging into if the file even existed in my bundle - and it did not!

So by using this code (also below): iPhone/iPad: Unable to copy folder from NSBundle to NSDocumentDirectory and the instructions for adding a directory properly to Xcode (from here and below)I was able to get it to work.

Copy folder into Xcode:

  1. Create a Directory on your Mac.
  2. Select Add Existing Files to your project
  3. Select the Directory you want to import
  4. In the pop-up window make sure you select "Copy items into destination group's folder" and "Create Folder References for any added folders"
  5. Hit "Add"
  6. The Directory should appear blue instead of yellow.

    -(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);
        }
    }
    

    }

======================== END EDIT

Frus-stray-shee-on! Anyway...

The code below copies my folder from the app bundle to the Documents folder in the simulator just fine. However on the device I get an error and no folder. Using ze Google I found out that the error (260) means the file (in this case my folder) does not exist.

What could be going wrong? Why can I not copy my folder from the bundle to the Documents? I have checked that the files exist - although the folder is not showing up - because Xcode wants flat file? Did it turn my folder (dragged into Xcode) into a flat file of assets instead?

I thank you for any assistance.

//  Could not copy report at path /var/mobile/Applications/3C3D7CF6-B1F0-4561-8AD7-A367C103F4D7/cmsdemo.app/plans.gallery to path /var/mobile/Applications/3C3D7CF6-B1F0-4561-8AD7-A367C103F4D7/Documents/plans.gallery. error Error Domain=NSCocoaErrorDomain Code=260 "The operation couldn’t be completed. (Cocoa error 260.)" UserInfo=0x365090 {NSFilePath=/var/mobile/Applications/3C3D7CF6-B1F0-4561-8AD7-A367C103F4D7/cmsdemo.app/plans.gallery, NSUnderlyingError=0x365230 "The operation couldn’t be completed. No such file or directory"}

NSString *resourceDBFolderPath;

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

if (success){
    NSLog(@"Success!");
    return;
} else {
    resourceDBFolderPath = [[[NSBundle mainBundle] resourcePath]
                                      stringByAppendingPathComponent:@"plans.gallery"];
    [fileManager createDirectoryAtPath: documentDBFolderPath attributes:nil];
    //[fileManager createDirectoryAtURL:documentDBFolderPath withIntermediateDirectories:YES attributes:nil error:nil];

    [fileManager copyItemAtPath:resourceDBFolderPath toPath:documentDBFolderPath           
                          error:&error];
}

    //check if destinationFolder exists
if ([ fileManager fileExistsAtPath:documentDBFolderPath])
{
    //removing destination, so source may be copied
    if (![fileManager removeItemAtPath:documentDBFolderPath error:&error])
    {
        NSLog(@"Could not remove old files. Error:%@",error);
        return;
    }
}
error = nil;
//copying destination
if ( !( [ fileManager copyItemAtPath:resourceDBFolderPath toPath:documentDBFolderPath error:&error ]) )
{
    NSLog(@"Could not copy report at path %@ to path %@. error %@",resourceDBFolderPath, documentDBFolderPath, error);
    return ;
}
like image 874
malaki1974 Avatar asked Mar 22 '12 20:03

malaki1974


1 Answers

I've taken the liberty of editing some of the code I feel needs a little housekeeping. You're using deprecated methods, overly-complicated methods, and just plain ridiculous if-elses. I would of course check that your file path is valid, having no idea what a .gallery file is, and making no attempt to provide a dummy one, the only judgement I can make is that your file path is simply invalid because the resource doesn't exist where you think it does. (At one point, you ask to copy the file into the documents directory, then check if it exists in your bundle!)

    -(void)testMethod {

    NSString *resourceDBFolderPath;

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

    if (success){
        NSLog(@"Success!");
        return;
    } 
    else {
        //simplified method with more common and helpful method 
        resourceDBFolderPath = [[NSBundle mainBundle] pathForResource:@"plans" ofType:@"gallery"];

        //fixed a deprecated method
        [fileManager createDirectoryAtPath:documentDBFolderPath withIntermediateDirectories:NO attributes:nil error:nil];

        [fileManager copyItemAtPath:resourceDBFolderPath toPath:documentDBFolderPath           
                              error:&error];

        //check if destinationFolder exists
        if ([ fileManager fileExistsAtPath:documentDBFolderPath])
        {
            //FIXED, another method that doesn't return a boolean.  check for error instead
            if (error)
            {
                //NSLog first error from copyitemAtPath
                NSLog(@"Could not remove old files. Error:%@", [error localizedDescription]);

                //remove file path and NSLog error if it exists.
                [fileManager removeItemAtPath:documentDBFolderPath error:&error];
                NSLog(@"Could not remove old files. Error:%@", [error localizedDescription]);
                return;
            }
        }
    }
}
like image 129
CodaFi Avatar answered Oct 31 '22 18:10

CodaFi