Как получить домашний каталог пользователей в изолированном приложении?

NSHomeDirectory() перенастраивает корень моей песочницы, а не мой домашний каталог. [@"~" stringByExpandingTildeInPath] делает то же самое.

Это /Users/username/Library/Containers/appID/Data и есть то, что возвращается. Как мне получить /Users/username/?


person Justin808    schedule 04.03.2012    source источник


Ответы (3)


Если вам нужен путь к реальному домашнему каталогу пользователя, вы можете использовать:

char *realHome = getpwuid(getuid())->pw_dir;

Полный пример:

#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <assert.h>

NSString *RealHomeDirectory() {
    struct passwd *pw = getpwuid(getuid());
    assert(pw);
    return [NSString stringWithUTF8String:pw->pw_dir];
}

Это дает вам путь к дому пользователя, но не дает автоматически доступ к этой папке. Как отмечено в комментариях, вы можете использовать этот путь для:

  • предоставление нормальной папки по умолчанию для диалогов открытия/сохранения
  • определение того, находитесь ли вы в песочнице, путем сравнения результата с NSHomeDirectory()
person CRD    schedule 04.03.2012
comment
Единственное, для чего он действительно хорош, — это установка разумного значения по умолчанию для диалогов открытия/сохранения файлов. Прямо сейчас, если я установлю NSHomeDirectory(), это будет не очень удобно для пользователя. Большинство людей даже не знают, что такое папка «Библиотека». - person Justin808; 04.03.2012
comment
Это одно хорошее применение, другое — проверить, находитесь ли вы в песочнице, сравнив ее с тем, что возвращает NSHomeDirectory(), и я уверен, что есть и другие... - person CRD; 04.03.2012
comment
И еще один — получить доступ к файлу через com.apple.security.temporary-exception.files.home-relative-path.* временные права. - person Dov; 30.04.2014
comment
Мне это было очень нужно, спасибо. Powerbox nsopenpanel в нашем приложении используется для выбора местоположения для нескольких различных применений, мы хотим сделать его хорошей отправной точкой для пользователя. Масштабное изменение значения всех команд пути к приложению — пародия. - person Tom Andersen; 15.10.2015
comment
Поскольку NSUserName() всегда должен возвращать правильное значение. Разве это не сработает нормально? NSString *realHomeDir = [NSString stringWithFormat@/Users/%@,NSUserName()]; - person Tibidabo; 24.04.2017
comment
@Tibidabo - ваше предложение сработает примерно в 99,99% случаев. Однако домашний каталог пользователя не обязательно должен находиться в /Users, и поэтому рекомендуется использовать метод, который возвращает домашний каталог пользователя, так как он всегда будет правильным, даже для редких 0,01% случаев, когда он находится где-то еще. (То же самое относится и к другим стандартным каталогам, для которых Apple предоставляет подпрограммы для определения их пути — используйте подпрограммы, если они доступны.) HTH - person CRD; 24.04.2017
comment
@CRD Спасибо за разъяснение. На самом деле я использую этот подход в одном из своих приложений, и один пользователь пожаловался, что не может использовать приложение. Вроде бы 100% надо использовать ваш подход - person Tibidabo; 24.04.2017

Из документации:

Доступ к данным пользователя

API-интерфейсы Mac OS X для поиска пути выше уровня POSIX возвращают пути относительно контейнера, а не относительно домашнего каталога пользователя. Если ваше приложение до того, как вы поместите его в песочницу, обращается к местоположениям в фактическом домашнем каталоге пользователя (~), и вы используете API-интерфейсы Cocoa или Core Foundation, то после включения песочницы ваш код поиска пути автоматически использует вместо этого контейнер вашего приложения.

При первом запуске изолированного приложения Mac OS X автоматически переносит основной файл настроек вашего приложения. Если ваше приложение использует дополнительные файлы поддержки, выполните однократную миграцию этих файлов в контейнер, как описано в разделе «Миграция приложения в песочницу».

Если вы используете команду POSIX, такую ​​как getpwuid, для получения пути к фактическому домашнему каталогу пользователя, рассмотрите вместо этого использование символа Cocoa или Core Foundation, такого как функция NSHomeDirectory. Используя Cocoa или Core Foundation, вы поддерживаете ограничение App Sandbox против прямого доступа к домашнему каталогу пользователя.

Если вашему приложению для работы требуется доступ к домашнему каталогу пользователя, сообщите Apple о своих потребностях, используя Система сообщений об ошибках Apple.

person Parag Bafna    schedule 04.03.2012

Используя Swift, вы можете получить доступ к пути к домашнему каталогу пользователей из изолированного приложения следующим образом:

var userHomeDirectoryPath : String {
    let pw = getpwuid(getuid())
    let home = pw?.pointee.pw_dir
    let homePath = FileManager.default.string(withFileSystemRepresentation: home!, length: Int(strlen(home)))

    return homePath
}


Я создал это решение на основе фрагмента из этого сообщения в блоге: http://zpasternack.org/accessing-the-real-home-folder-from-a-sandboxed-app/

person Robin Schmidt    schedule 17.10.2017