Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the equivalent of NSHomeDirectory() in CoreFoundation?

I have a C library I'm modifying, as little as possible, to add a feature and get that to run properly on iOS. It is working fine on iOS 5.1, but breaking on iOS 6 because it's required to write a small temporary file, and I think there is an issue w/ Entitlements with where it used to write (/tmp/some.file).

I know that NSHomeDirectory() will give me the sandbox root from objectiveC, but it requires objectiveC / Foundation to run. How can I get the sandbox root using only C / CoreFoundation calls?

like image 848
codehearted Avatar asked Oct 03 '12 17:10

codehearted


2 Answers

The CoreFoundation equivalent of NSHomeDirectory() is CFCopyHomeDirectoryURL(). It is available since iOS 5 and the only place where it is “documented” is in the iOS 4.3 to iOS 5.0 API Differences.

If you want the temporary directory without hardcoding the tmp string, then you may want to use confstr with the _CS_DARWIN_USER_TEMP_DIR constant and fallback to the TMPDIR environment variable if the confstr call fails:

char tmpdir[PATH_MAX];
size_t n = confstr(_CS_DARWIN_USER_TEMP_DIR, tmpdir, sizeof(tmpdir));
if ((n <= 0) || (n >= sizeof(tmpdir)))
    strlcpy(tmpdir, getenv("TMPDIR"), sizeof(tmpdir));
CFURLRef tmp = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (UInt8 *)tmpdir, strlen(tmpdir), true);
like image 164
0xced Avatar answered Nov 10 '22 07:11

0xced


There is no "home" directory on iOS.

Your app is in a sandbox, so you don't have access to /tmp.

Instead, you have a tmp directory inside your application's sandbox.

You can use CFBundle to get the path to your app.
The temp folder can then be found by adding ../tmp/.

Basically:

CFBundleRef         bundle;
CFURLRef            url;
CFStringRef         bundlePath;
CFStringRef         tmpRelPath;
CFMutableStringRef  tmpPath;

bundle      = CFBundleGetMainBundle();
url         = CFBundleCopyBundleURL( bundle );
bundlePath  = CFURLCopyFileSystemPath( url, kCFURLPOSIXPathStyle );
tmpRelPath  = CFSTR( "/../tmp/" );
tmpPath     = CFStringCreateMutable( kCFAllocatorDefault, CFStringGetLength( bundlePath ) + CFStringGetLength( tmpRelPath ) );

CFStringAppend( tmpPath, bundlePath );
CFStringAppend( tmpPath, tmpRelPath );

CFShow( tmpPath );

CFRelease( url );
CFRelease( bundlePath );
CFRelease( tmpPath );
like image 27
Macmade Avatar answered Nov 10 '22 09:11

Macmade