Можно ли как-нибудь предоставить моему изолированному приложению Mac доступ только для чтения к файлам в ~/Library?
Я немного запутался с песочницей. Это возможно?
Спасибо!
1 ответ
Да, но это требует права "временного исключения". "Временный" означает, что он может исчезнуть в какой-то будущей версии ОС, но это не представляет особой опасности. Более серьезная проблема заключается в том, что слово "исключение" означает, что вам придется обосновать использование вами права, иначе рецензенты App Store, вероятно, отклонят вас.
Подайте отчет об ошибке, объясняющий, что именно вы думаете, что вы должны сделать, но сегодня вы не можете обойтись без доступа к ~/Library
, а в идеале также начать ветку форума по теме. Они могут предложить обходной путь для использования вместо доступа ~/Library
(возможно, даже используя частные API), в этом случае делайте то, что они говорят. Или они могут сказать, чтобы использовать временное исключение на данный момент, в этом случае, сделать это. Или они могут не отвечать, в этом случае вы используете временное исключение и скрещиваете пальцы. В любом случае, убедитесь, что в ваших примечаниях к обзору в App Store есть ссылка на отчет об ошибке и / или ветку форума.
Для этого вам нужно будет вручную отредактировать список разрешений вашего проекта, но это не очень сложно. Создать com.apple.security.temporary-exception.files.home-relative-path.read-only
массив, с одной строкой, "/Library/"
, Как это:
<key>com.apple.security.temporary-exception.files.home-relative-path.read-only</key>
<array>
<string>/Library/</string>
</array>
Экстра /
в конце песочница узнает, что вы хотите получить доступ к каталогу, а не к файлу. Если вы отключите его, вы получите доступ ко всем файлам в ~/Library
, что вы просили, но не для файлов в (рекурсивных) подкаталогах ~/Library
как, скажем, ~/Library/LaunchAgents/com.mycompany.myapp.myoldagent.12345678-ABCD-EF00-1234-567890ABCDEF.plist
, что вы, вероятно, хотите. См. Временные расширения доступа к файлам в справочной документации по ключу права.
Также обратите внимание, что у вас уже есть доступ "бесплатно" к определенным вещам в ~/Library
либо потому, что они скопированы в ваш контейнер, либо косвенно, когда вы используете соответствующие API вместо путей. Таким образом, может быть лучший способ выполнить то, что вы делаете - например, для чтения файлов, оставленных предыдущей версией вашего приложения без песочницы, вы можете перенести их в контейнер и прочитать их там.
Еще одна вещь: просто доступ к ~/ Библиотека не меняет то, что NSHomeDirectory()
, URLsForDirectory:inDomains:
и т. д. вернется - вы все равно получите ~/Containers/com.mycompany.myproduct/Data/Library
вместо. Полуофициальная рекомендация Apple для решения этой проблемы заключается в использовании BSD API для получения реального домашнего каталога пользователя, и самый простой способ заключается в следующем:
const char *home = getpwuid(getuid())->pw_dir;
NSString *path = [[NSFileManager defaultManager]
stringWithFileSystemRepresentation:home
length:strlen(home)];
NSURL *url = [NSURL fileURLWithPath:path isDirectory:YES];
Несколько заметок:
- Как правило, это не очень хорошая идея, чтобы позвонить
getpwuid
слишком часто Лучшее решение - вызвать этот код один раз пораньше, а затем кэшироватьNSURL
, - Это, очевидно, может также использоваться, чтобы получить дом других пользователей (и, следовательно,
Library
), но App Store почти наверняка не допустит никакого программного обеспечения, которое действительно пытается это сделать. - Тот факт, что библиотека находится на
~/Library
считается "деталью реализации", которая может измениться однажды, что является еще одной причиной (помимо права), что это следует рассматривать как временный обходной путь до тех пор, пока Apple не предоставит реальное решение вашей проблемы более высокого уровня, и это может быть Стоит упомянуть в заметках к вашему обзору.