2012-06-08 22 views

Odpowiedz

26

Tak, ale wymaga uprawnienia "wyjątek tymczasowy". "Tymczasowy" oznacza, że ​​może zniknąć w jakiejś przyszłej wersji systemu operacyjnego, ale nie stanowi to dużego ryzyka. Większym problemem jest słowo "wyjątek": oznacza to, że będziesz musiał uzasadnić swoje uprawnienie, lub recenzenci App Store prawdopodobnie Cię odrzucą.

Złóż raport o błędzie wyjaśniający dokładnie, co według ciebie powinieneś być w stanie zrobić, ale nie może zrobić tego dzisiaj bez dostępu do ~/Library, a najlepiej również rozpocząć wątek na forum na ten temat. Mogą zaproponować obejście, którego można użyć zamiast uzyskać dostęp do ~/Library (może nawet przy użyciu prywatnych interfejsów API), w takim przypadku wykonaj to, co powiedzą. Mogą też powiedzieć, że używają tymczasowego wyjątku na razie, w takim przypadku, zrób to. Mogą też nie odpowiadać, w takim przypadku użyjesz wyjątku tymczasowego i skrzyżujesz palce. W każdym razie upewnij się, że twoje notatki z przeglądu aplikacji App Store zawierają link do zgłoszenia błędu i/lub wątku na forum.

Będziesz musiał edytować uprawnienia do pliku projektu ręcznie, aby to zrobić, ale nie jest to trudne. Utwórz tablicę com.apple.security.temporary-exception.files.home-relative-path.read-only z jednym ciągiem, "/Library/". Tak:

<key>com.apple.security.temporary-exception.files.home-relative-path.read-only</key> 
<array> 
    <string>/Library/</string> 
</array> 

Dodatkowy / w końcu jest jak piaskownica wie chcesz uzyskać dostęp do katalogu, zamiast pliku. Jeśli go nie wybierzesz, uzyskasz dostęp do wszystkich plików w ~/Library, o co prosiłeś, ale nie do plików w (rekursywnych) podkatalogach ~/Library, takich jak, powiedzmy, ~/Library/LaunchAgents/com.mycompany.myapp.myoldagent.12345678-ABCD-EF00-1234-567890ABCDEF.plist, czego prawdopodobnie potrzebujesz. Zobacz File Access Temporary Extensions w dokumentacji Reference Key Reference.

Zauważ, że masz już dostęp "za darmo" do pewnych rzeczy pod ~/Library, ponieważ są one kopiowane do kontenera lub pośrednio, gdy używasz odpowiednich interfejsów API zamiast używania ścieżek. Może więc istnieć lepszy sposób na wykonanie tego, co robisz - na przykład, aby odczytać pliki pozostawione przez poprzednią wersję aplikacji bez piaskownicy, możesz je przenieść do kontenera i tam je przeczytać.

Jeszcze jedno: posiadanie dostępu do katalogu ~/Library nie zmienia tego, co zostanie zwrócony: NSHomeDirectory(), URLsForDirectory:inDomains: itd. - w dalszym ciągu otrzymasz numer ~/Containers/com.mycompany.myproduct/Data/Library. pół-oficjalna rekomendacja Apple do czynienia z tego jest użycie BSD API, aby uzyskać prawdziwy katalog domowy użytkownika, a najprostszym sposobem jest taka:

const char *home = getpwuid(getuid())->pw_dir; 
NSString *path = [[NSFileManager defaultManager] 
        stringWithFileSystemRepresentation:home 
        length:strlen(home)]; 
NSURL *url = [NSURL fileURLWithPath:path isDirectory:YES]; 

Kilka uwag:

  • to nie jest na ogół dobry pomysł, aby zbyt często dzwonić pod numer getpwuid. Najlepszym rozwiązaniem jest wywołanie tego kodu raz na początku, a następnie buforowanie wynikowego NSURL.
  • Oczywiście można to również wykorzystać do uzyskania katalogów domowych innych użytkowników (a zatem i Library), ale App Store prawie na pewno nie zezwoli na oprogramowanie, które faktycznie spróbuje.
  • Fakt, że biblioteka znajduje się pod numerem ~/Library jest uważany za "szczegół wdrażania", który może ulec zmianie jeden dzień, co jest kolejnym powodem (na górze uprawnienia), że należy to traktować jako tymczasowe obejście, dopóki Apple nie dostarczy prawdziwego rozwiązania do problemu wyższego poziomu i warto wspomnieć o nim w uwagach do recenzji.
+0

dzięki za odpowiedź! – dot

+0

Wycofane, chociaż proponowane przez ciebie rozwiązanie użycia 'getpwent() -> pw_dir' zwraca mi'/var/virusmails'. –

+2

To działało dla mnie: 'getpwnam ([NSUserName() UTF8String]) -> pw_dir' –