views:

84

answers:

1

Hi,

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

+2  A: 

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]);
    }
Vladimir
Thanks for the response, but this is not what I want to do. What I want to do is copy the contents of the Populator folder to the directories root (not a folder called Populator in the documents root). What you are saying to do does work, but is not what I want to achieve.
Jack
Thanks a lot, the misunderstanding was almost certainly my fault. I am using this code for an iPad application, so will be targeting iOS 3.2, although eventually this will support iOS4. Thanks for your code, any idea how to get it working for 3.2 (without blocks)?
Jack
I've added code using fast enumeration. blocks solution was more to exercise myself - blocks are a new concept for me.
Vladimir
Thank you so much, really appreciate the effort.
Jack