views:

728

answers:

2

I'm new to Mac and Objective-C, so I may be barking up the wrong tree here and quite possibly there are better ways of doing this.

I have tried the code below and it doesn't seem right. It seems I don't get the correct length in the call to FSCreateDirectoryUnicode. What is the simplest way to accomplish this?

NSString *theString = @"MyFolderName";
NSData *unicode = [theString dataUsingEncoding:NSUnicodeStringEncoding allowLossyConversion:NO];
FSCreateDirectoryUnicode(&aFolderFSRef, [theString length], [unicode bytes], kFSCatInfoNone, NULL, &newFolderFSRef, NULL, NULL);
+3  A: 

There are a couple of issues with your raw string data. But the easiest way to do it in Cocoa is:

NSString *theString = @"MyFolderName";

NSString* path = [NSHomeDirectory() stringByAppendingPathComponent:theString];
[[NSFileManager defaultManager] createDirectoryAtPath:path
                                           attributes:nil];

You did use an FSRef to specify the path to where the directory was created. My example uses the home directory instead. If you really have to use the directory in the FSRef and do not know the path to it, it might be easier to use the FSCreateDirectoryUnicode function:

Edit: changed code to use correct encoding.

NSString *theString = @"MyFolderName";
const UniChar* name = (const UniChar*)[theString cStringUsingEncoding:NSUnicodeStringEncoding];
FSCreateDirectoryUnicode(&aFolderFSRef, [theString length], name, kFSCatInfoNone, NULL, &newFolderFSRef, NULL, NULL);

The only thing that was broken in the original code, was that dataUsingEncoding returns the external representation of the string. That means that the data contains a unicode byte order mark at the beginning, which FSCreateDirectoryUnicode does not want.

Nikolai Ruhe
Thanks - that helped! (after realizing that FSFileManager should be NSFileManager)
staffan
FSCreateDirectoryUnicode expects a string of UniChar 16 bit characters, not a UTF8 string, so that second example will not work.
Peter N Lewis
Shame on me: one severe mistake and a typo in one answer.Edited answer for correctness, sorry for the confusion. Thanks Peter.
Nikolai Ruhe
A: 

Your code looks OK. I would use [unicode length]/2 as the length, although that should be equal to [theString length] in all (or at least almost all) cases.

Alternatively, you can use Nathan Day's NDAlias NSString+NDCarbonUtilities category

+ (NSString *)stringWithFSRef:(const FSRef *)aFSRef
{
    NSString  * thePath = nil;
    CFURLRef theURL = CFURLCreateFromFSRef( kCFAllocatorDefault, aFSRef );
    if ( theURL )
    {
     thePath = [(NSURL *)theURL path];
     CFRelease ( theURL );
    }
    return thePath;
}

to get the path for your FSRef and then Nikolai's solution:

NSString* aFolderPath = [NSString stringWithFSRef:aFolderFSRef];
NSString* path = [aFolderPath stringByAppendingPathComponent:theString];
[[FSFileManager defaultManager] createDirectoryAtPath:path attributes:nil];
Peter N Lewis