tags:

views:

34

answers:

2

I'm trying to save a CFPropertyList to a location in the user's home folder. Using the code below I'm getting errorCode = -10 (unknown error).

CFURLRef fileURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR("~/testfile.txt"),  kCFURLPOSIXPathStyle, false );  

SInt32 errorCode;
Boolean status = CFURLWriteDataAndPropertiesToResource(fileURL, xmlData, NULL, &errorCode);

If I change the path to something like "/testfile.txt" without the '~' then everything works. How can one save a property list to the current user's home folder? Must one obtain the user's name first and include it in the path such as /users/toffler/testfile.txt?

+2  A: 

Automatic ~ expansion is a feature of the shell.

If you are using Cocoa/Foundation, you can use the NSString methods

- (NSString *)stringByAbbreviatingWithTildeInPath;
- (NSString *)stringByExpandingTildeInPath;

otherwise, you'll have to write some code yourself to do this. Getting the user's login name and constructing the path /Users/login-name/ is not the correct way to do this. (While most users will have their home directory here, some will not.)

Jim Correia
Thanks Jim. After reading your answer I found the CoreFoundation version that I also need here. http://developer.apple.com/mac/library/qa/qa2007/qa1549.html
Stephen Blinkhorn
+2  A: 

With Foundation, you can call the NSHomeDirectory function to get the absolute path to the user's home directory. You can then use the path-manipulation methods of NSString or of NSURL, or the equivalent function for CFURL, to tack a sub-path onto that.

However, please don't put files into the top level of my Home folder unless I, as the user, tell you to.

  • If you want to save a file at the user's request, run a save panel, and then save it where the user told you to.
  • If you want to save a preferences file, you probably should be using NSUserDefaults or CFPreferences, instead of handling plists yourself.
  • If you have some other reason to save a user-specific file, it should generally go into either the chewable items folder, the Caches folder, or the Preferences folder. The two functions that I linked to are the easiest ways to access those two of those three folders; the harder way, and the only one that works on all three, is the FSFindFolder function. Unlike most of the Folder Manager, FSFindFolder is not deprecated and is available in 64-bit.
Peter Hosey
NSHomeDirectory works really well with NSString's stringByAppendingPathComponent.
Stephen Blinkhorn
Stephen Blinkhorn: Yeah, but see the rest of my answer. You really shouldn't be putting files in the top level of the Home folder unless I (the user) tell you to in a Save panel, in which case you already have the complete path and don't need to assemble it.
Peter Hosey