Question

So I'm kind of a Cocoa n00b, but I'm writing this simple little program and I can't get the NSFileManager delegate method "shouldProceedAfterError..." to fire. Here's the code I'm running in my AppDelegate

-(BOOL)copyFile {
    [[NSFileManager defaultManager] setDelegate:self];

    NSError *copyError = nil;
    NSString *filename = [[NSString alloc] initWithString:[[[self.sourceFile path] componentsSeparatedByString:@"/"] lastObject]];
    NSString *destination = [[[[[UserData sharedData] folderLocation] path] stringByAppendingString:@"/"] stringByAppendingString:filename];

    [[NSFileManager defaultManager] copyItemAtPath:[self.sourceFile path] toPath:destination error:&copyError];

    NSLog(@"error! %@",copyError);

    [filename release];
    return YES;
}

- (BOOL)fileManager:(NSFileManager *)fileManager shouldProceedAfterError:(NSError *)error copyingItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath {
    NSLog(@"more error... %@",error);
    return NO;
}
- (BOOL)fileManager:(NSFileManager *)fileManager shouldCopyItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath {
    NSLog(@"in shouldCopyItemAtPath...");
    return YES;
}

The situation I'm trying to deal with is if the file already exists at the destination. I do get an error, but I never get that "more error..." trace to output. I also DO get that trace from shouldCopyItemAtPath: so I'm not exactly sure why the method isn't firing?

Am I going crazy, how did I mess up the delegate implementation here? Thanks for any help!

Was it helpful?

Solution

This is just a hypothesis, but since copyItemAtPath:toPath:error is defined such that "The file specified in srcPath must exist, while dstPath must not exist prior to the operation.", perhaps the scenario where dstPath already exists isn't considered an "error," and so doesn't fire the delegate.

i.e. perhaps "It's not an error if you do something we told you not to do."

You can always do the check and delete it yourself:

NSFileManager* fileManager = [NSFileManager defaultManager];

// Delete the file if it already exists.
if ([fileManager fileExistsAtPath: destination])
        if (![fileManager removeItemAtPath: destination error: error])
                return NO;

return [fileManager copyItemAtPath: source toPath: destination error: error];

OTHER TIPS

Probably you are providing a wrong path as source?
copyItemAtPath does not call the delegate methods if the the source path is invalid.
You can test that if you use the following method:

-(IBAction)copyFile:(id)sender
{
    [[NSFileManager defaultManager] setDelegate:self];
    NSError* copyError = nil;
    NSString* sourceFilepath = [@"~/Desktop/source.txt" stringByExpandingTildeInPath];
    NSString* targetFilepath = [@"~/Desktop/target.txt" stringByExpandingTildeInPath];  
    [[NSFileManager defaultManager] copyItemAtPath:sourceFilepath toPath:targetFilepath error:&copyError];  
    NSLog(@"Error:%@", copyError);  
}

When calling that method I notice the following behavior:

  • If ~/Desktop/source.txt is a file and ~/Desktop/target.txt does not exist:
    • NSFileManager calls the shouldCopyItemAtPath delegate method
  • If ~/Desktop/source.txt is a file and ~/Desktop/target.txt exists:
    • NSFileManager first calls the shouldCopyItemAtPath and shouldProceedAfterError
  • If ~/Desktop/source.txt does not exist
    • NSFileManager does not call any delegate method and just returns a NSError objet
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top