iPhone (iOS): copying files from main bundle to documents folder error

Jack picture Jack · Jul 14, 2010 · Viewed 17.2k times · Source

I am trying to copy some files across from my app bundle to the documents directory on first launch. I have the checks in place for first launch, but they're not included in code snippet for clarity. The problem is that I am copying to the documents directory (which already exists) and in the documentation, it states that:

dstPath must not exist prior to the operation.

What is the best way for me to achieve the copying straight to the documents root? The reason I want to do this is to allow iTunes file sharing support.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
  NSString *sourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Populator"];

  NSLog(@"\nSource Path: %@\nDocuments Path: %@", sourcePath, documentsDirectory);

  NSError *error = nil;

  if([[NSFileManager defaultManager] copyItemAtPath:sourcePath toPath:documentsDirectory error:&error]){
    NSLog(@"Default file successfully copied over.");
  } else {
    NSLog(@"Error description-%@ \n", [error localizedDescription]);
    NSLog(@"Error reason-%@", [error localizedFailureReason]);
  }
  ...
  return YES;
}

Thanks

Answer

Vladimir picture Vladimir · Jul 14, 2010

Your destination path must contain the name of item being copied, not just the documents folder. Try:

if([[NSFileManager defaultManager] copyItemAtPath:sourcePath 
          toPath:[documentsDirectory stringByAppendingPathComponent:@"Populator"]
          error:&error]){
...

Edit: Sorry misunderstood your question. Don't know if there's a better option then iterating through folder contents and copy each item separately. If you're targeting iOS4 you can use NSArray's -enumerateObjectsUsingBlock: function for that:

NSArray* resContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:copyItemAtPath:sourcePath error:NULL];
[resContents enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
    {
        NSError* error;
        if (![[NSFileManager defaultManager] 
                  copyItemAtPath:[sourcePath stringByAppendingPathComponent:obj] 
                  toPath:[documentsDirectory stringByAppendingPathComponent:obj]
                  error:&error])
            DLogFunction(@"%@", [error localizedDescription]);
    }];

P.S. If you can't use blocks you can use fast enumeration:

NSArray* resContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:copyItemAtPath:sourcePath error:NULL];

for (NSString* obj in resContents){
    NSError* error;
    if (![[NSFileManager defaultManager] 
                 copyItemAtPath:[sourcePath stringByAppendingPathComponent:obj] 
                 toPath:[documentsDirectory stringByAppendingPathComponent:obj]
                 error:&error])
            DLogFunction(@"%@", [error localizedDescription]);
    }