2012-10-03 5 views
6

У меня есть библиотека C Я модифицирую, как можно меньше, чтобы добавить функцию и заставить ее нормально работать на iOS. Он отлично работает на iOS 5.1, но ломается на iOS 6, потому что требуется написать небольшой временный файл, и я думаю, что есть проблема с правами, с которыми она использовалась для записи (/tmp/some.file).Что эквивалентно NSHomeDirectory() в CoreFoundation?

Я знаю, что NSHomeDirectory() предоставит мне корень песочницы из objectC, но для этого требуется, чтобы objectC/Foundation запускался. Как я могу получить root песочницы, используя только вызовы C/CoreFoundation?

+0

У вас есть доступ к 'NSSearchPathForDirectoriesInDomains'? Или это имеет ту же проблему? – Rob

+0

Вы действительно ищете домашний каталог или просто временный каталог для хранения файла? –

+0

@Rob Префикс NS подразумевает Foundation. – Macmade

ответ

8

CoreFoundation эквивалент NSHomeDirectory() является CFCopyHomeDirectoryURL(). Он доступен с iOS 5, и единственное место, где он «задокументирован», находится в iOS 4.3 to iOS 5.0 API Differences.

Если вы хотите, чтобы временный каталог без жесткого кодирования tmp строки, то вы можете использовать confstr с постоянной _CS_DARWIN_USER_TEMP_DIR и возврат к переменной в TMPDIR среде, если вызов confstr не удается:

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); 
+0

Понадобилось некоторое время, чтобы проверить, но это, по-видимому, немного точнее ответа (ну, на самом деле, два ответа - но это то, что я имею в виду), поэтому я переключу выбранный ответ на этот. Насколько я могу судить, все они правильны. – codehearted

+1

использовать n> sizeof (tmpdir) вместо n> = sizeof (tmpdir) –

+0

Вероятно, вы должны добавить окончательный резерв в '/ tmp' в случае, если' confstr() 'fail и' $ TMPDIR' не установлен. Это лучше, чем неудача. – Mecki

5

В iOS нет директории "home".

Ваше приложение в изолированном поле, так что у вас нет доступа к /tmp.

Вместо этого у вас есть папка tmp внутри песочницы вашего приложения.

Вы можете использовать CFBundle, чтобы получить доступ к своему приложению.
Временную папку можно найти, добавив ../tmp/.

В основном:

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); 
+0

Это похоже на то, что я хотел, спасибо - я дам вам знать, как это работает, когда я попробую. – codehearted

+0

У меня все еще возникают проблемы с записью (получение плохого доступа к fprintf), но приведенный выше код действительно правильно устанавливает местоположение внутри песочницы, поэтому я считаю это правильным. Еще раз спасибо. – codehearted

Смежные вопросы