“No such file or directory” Error when creating di

2019-06-22 08:24发布

问题:

I am attempting to save thumbnails of user generated photos in a subdirectory in the documents directory, but I am unable to create the subdirectory in the first place. When I attempt to create the subdirectory in the documents directory I get this error (No such file or directory):

Error Domain=NSCocoaErrorDomain Code=4 "The operation couldn’t be completed. (Cocoa error 4.)"
UserInfo=0x17ef9c90 {NSFilePath=/var/mobile/Applications/FD0CC480-97FE-4E50-931F-5341DB6AD92B/Documents/com.Jonathan.App-Name/707F0431-7A09-4D33-B122-13C48AD4CA53, 
NSUnderlyingError=0x17e51520 "The operation couldn’t be completed. No such file or directory"}

I'm so confused. I know the directory doesn't exist because I'm trying to create it! The only thing I can think of is that the documents directory is incorrect, but that is straight from the Apple Docs.

Am I incorrectly trying to create the subdirectory?

- (NSURL *)documentsDirectory
{
    NSFileManager *sharedFM = [NSFileManager defaultManager];

    NSArray *possibleURLs = [sharedFM URLsForDirectory:NSDocumentDirectory
                                             inDomains:NSUserDomainMask];

    NSURL *appSupportDir = nil;
    NSURL *appDirectory = nil;

    if ([possibleURLs count] >= 1)
    {
        // Use the first directory (if multiple are returned)
        appSupportDir = [possibleURLs objectAtIndex:0];
    }

    // If a valid app support directory exists, add the
    // app's bundle ID to it to specify the final directory.
    if (appSupportDir)
    {
        NSString *appBundleID = [[NSBundle mainBundle] bundleIdentifier];

        appDirectory = [appSupportDir URLByAppendingPathComponent:appBundleID];
    }

    return appDirectory;
}

- (NSURL *)thumbnailDirectoryWithName:(NSString *)theName
{
    NSURL *directory = [[self documentsDirectory] URLByAppendingPathComponent:theName];
    NSURL *thumbnailsDirectory = [directory URLByAppendingPathComponent:@"Thumbnails"];

    NSError *error;

    if ([[NSFileManager defaultManager] fileExistsAtPath:[thumbnailsDirectory path]] == NO)
    {
        [[NSFileManager defaultManager] createDirectoryAtURL:thumbnailsDirectory withIntermediateDirectories:NO attributes:nil error:&error];

        if (error)
        {
            NSLog(@"[Thumbnail Directory] %@", [error description]);

            return nil;
        }
    }

    return thumbnailsDirectory;
}

I have also tried createDirectoryAtPath: and stringByAppendingPathComponent: with no avail.

The NSURL *directory in thumbnailDirectoryWithName: returns:

/var/mobile/Applications/FD0CC480-97FE-4E50-931F-5341DB6AD92B/Documents/com.Jonathan.App-Name/707F0431-7A09-4D33-B122-13C48AD4CA53

The last component of the file path, 707F0431-7A09-4D33-B122-13C48AD4CA53, is the unique identifier for an Entity in Core Data, which enables me to uniquely name a directory.

Any help is greatly appreciated!

回答1:

Here's the way to get the documents directory:

- (NSString *)documentsDirectory {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    return (paths.count)? paths[0] : nil;
}

Then, to build the path to your file:

- (NSURL *)thumbnailDirectoryWithName:(NSString *)theName {

    NSString *namePath = [[self documentsDirectory] stringByAppendingPathComponent:theName];
    NSString *thumbnailsPath = [namePath stringByAppendingPathComponent:@"Thumbnails"];
    NSURL *thumbnailsURL = [NSURL fileURLWithPath:thumbnailsPath];

    NSError *error;

    if ([[NSFileManager defaultManager] fileExistsAtPath:thumbnailsPath] == NO) {
        [[NSFileManager defaultManager] createDirectoryAtURL:thumbnailsURL withIntermediateDirectories:NO attributes:nil error:&error];

        if (error) {
            NSLog(@"[Thumbnail Directory] %@", [error description]);
            return nil;
        }
    }
    return thumbnailsURL;
}


回答2:

I've accepted @danh answer, but I found the reason for getting this error. It was a simple mistake and another reason why I shouldn't code when I'm tired, haha. I can't find a reason why Apple suggests we include the application bundle identifier as a subdirectory name, but to fix this error all I had to do was set withIntermediateDirectories:YES.

withIntermediateDirectories:

If YES, this method creates any non-existent parent directories as part of creating the directory in url. If NO, this method fails if any of the intermediate parent directories does not exist.

Basically, I was trying to create a subdirectory in a directory that did not exist.