2012-04-21 12 views
16

Jestem piaskownica mojej aplikacji i próbuję pozwolić na import/eksport wielu plików, używając pliku XML, aby się do nich odwoływać. Aby umożliwić mojej aplikacji (lub innej aplikacji piaskownicy) dostęp do plików wymienionych w pliku XML, dołączam także serializowaną zakładkę o zakresie zabezpieczeń. Serializuję go tak, jak opisano w this answer, a moje testy jednostkowe (które są nie piaskowane) zapisują i odczytują dane XML bez problemu. Kiedy moja aplikacja rozwiązuje zakładkę, zwracana wartość NSURL jest zerowa, podobnie jak odniesienie NSError. Ponieważ nie sądzę, aby tak było, dlaczego tak się dzieje? Mogę obejść go, zachęcając użytkownika do wybrania pliku/katalogu z numerem NSOpenPanel, ale nadal chciałbym, aby zakładki działały tak, jak powinny.Piaskownica aplikacji: zakładka o zakreślonym dokumencie nie została rozwiązana; nie zwracam żadnego błędu

zamieszczonym w projekcie testowym

Aby odtworzyć w domu, utwórz nową aplikację kakao w Xcode i kliknąć na poniższy GIST dla plików w projekcie: https://gist.github.com/2582589 (aktualizowana o odpowiedniej następnej widzenia pętla)

Następnie wykonaj Apple's instructions, aby podpisać kod projektu. Odtworzyć problem (który przesłałem do Apple jako rdar://11369377), klikając kolejno przyciski. Wybieramy dowolny plik na dysku (poza kontenerem aplikacji), następnie XML do eksportu do, a następnie ten sam XML do importu.

Mam nadzieję, że będziecie w stanie mi pomóc dowiedzieć się, co robię źle. Albo robię coś złego i ramy błędnie trzymają się same, albo robię to dobrze i jest całkowicie zepsute. Próbuję nie blame the framework, więc co to jest? Czy jest jeszcze inna możliwość?

Przykładowy kod

Eksport XML do docURL:

// After the user picks an XML (docURL) destination with NSSavePanel 

[targetURL startAccessingSecurityScopedResource]; 
NSData *bookmark = [targetURL bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope 
         includingResourceValuesForKeys:nil 
             relativeToURL:docURL 
               error:&error]; 
[targetURL stopAccessingSecurityScopedResource]; 

Importowanie XML z docURL:

// After the user selected the XML (docURL) from an NSOpenPanel 

NSURL *result = [NSURL URLByResolvingBookmarkData:bookmarkData 
              options:NSURLBookmarkResolutionWithSecurityScope 
            relativeToURL:docURL 
           bookmarkDataIsStale:nil 
              error:&error]; 

Próbowałem wokół tego połączenia z [docURL ..AccessingSecurityScopedResource], które nie zrobić różnicę (zgodnie z oczekiwaniami, ponieważ docursL jest już w zasięgu po wybraniu w Otwórz Panel

także określić następujące w moim app.entitlements pliku:

com.apple.security.files.user-selected.read-write 
com.apple.security.files.bookmarks.app-scope 
com.apple.security.files.bookmarks.collection-scope 

Jak wspomniano powyżej, drugi etap (rozwiązywanie zakładkę) uzupełnia, ale pozostawia zarówno error i result zero. Ponieważ wdrażam sandboxing, większość błędów, które popełniłem, spowodowało zwrócenie NSError, co pomogło mi rozwiązać problem. Ale teraz nie ma błędu i nie rozwiązano adresu URL.

Różne rozwiązywanie problemów kroki

  • Próbowałem umieszczenie pliku XML do mojego aplikacji piaskownicy, która nie uczynić różnicę, więc dostęp do pliku XML nie jest problemem

  • Aplikacja używa ARC, ale także testy jednostkowe, które się powiodły. Próbowałem za pomocą alloc/init zamiast autoreleased metody klasy, zbyt (na wszelki wypadek)

  • I wklejony kod rozdzielczości URL natychmiast po utworzeniu zakładki, i to działa dobrze, tworząc bezpieczeństwa o zasięgu URL

  • Zrobiłem po na pierwotnie utworzonej zakładce (przed serializacją), a następnie na zakładce po deserializacji i pasują one do 100%. Serializacja nie jest problemem.

  • Wymieniłem wywołanie rozdzielczości na CFURLCreateByResolvingBookmarkData(..), bez żadnych zmian. Jeśli jest to błąd, to jest obecna w API Fundacji rdzenia oraz warstwy Cocoa

  • określając wartość bookmarkDataIsStale: nie ma wpływu

  • Gdybym określić 0 dla options:, potem zrobić odzyskać prawidłowy NSURL, ale nie ma zasięgu zabezpieczeń, a zatem kolejne wywołania do odczytu pliku nadal się nie udają

    Innymi słowy, zserializowana zakładka wydaje się być poprawna. Jeżeli dane zakładki zostały uszkodzone, wątpię bibliotece NSURL byłby w stanie nic zrobić z nim

  • NSURL.h nie zawierają żadnych użytecznych komentarzy podkreślić coś robię źle

Czy ktoś używanie zakładek z zakresem zabezpieczeń w aplikacji piaskownicy z powodzeniem? Jeśli tak, to co robisz inaczej niż ja?

OS Version Zapytanie

Może ktoś z dostępem do beta Mountain Lion zweryfikować, czy mój projekt próbka pokazuje ten sam (e) brak błędu? Jeśli jest to błąd, który został naprawiony po Lwie, nie będę się tym martwić. Nie jestem jeszcze w programie dla programistów, więc nie mam do niego dostępu. Nie jestem pewien, czy odpowiedź na to pytanie naruszałaby NDA, ale mam nadzieję, że nie.

+0

Wcale nie mogłem pomóc, ale to pytanie jest trochę dziennika podróży w trakcie eksploracji. Byłoby wspaniale, gdybyś mógł to przerobić, zapominając o tym, JAK DOSTAŁES SIĘ DO ZROBIENIA. Bez obrazy: pytanie wydaje się być wysokiej jakości, które odzwierciedla 5 upvotes (obecnie 6 z moimi). –

+0

@Dzięki za dane wejściowe i przekazane. Zachowałem (większość) aktualizacji z dwóch powodów. Przede wszystkim dokumentuję kroki, które próbowałem, aby inni mogli uniknąć powtarzającego się rozwiązywania problemów, a po drugie, umieściłem aktualizacje na dole (zamiast dodawać nowe informacje do głównego pytania), aby wyjaśnić osobom podążającym za pytaniem: faktycznie zmienione. Planowałem edytować pytanie po otrzymaniu odpowiedzi. Sugerujesz zmianę treści w pytaniu lub usunięcie mniej istotnych elementów? – Dov

+0

zarówno. Zwiększyłoby to Twoje szanse na uzyskanie odpowiedzi, a także sprawiło, że post byłby bardziej trafny dla przyszłych użytkowników, którzy mają zupełnie inne eksploracje, ale ten sam problem. Wiesz, rozwiń problem;) –

Odpowiedz

5

W kodzie Gist, zmień następującą linię w AppDelegate.m (linia 61):

[xmlTextFileData writeToURL:savePanel.URL atomically:YES]; 

do

[xmlTextFileData writeToURL:savePanel.URL atomically:NO]; 

Twój kod będzie wtedy działać.

Powodem tego jest prawdopodobnie ten sam powód, dla którego konieczne jest posiadanie istniejącego (ale pustego) pliku, który będzie zawierać zakładki o zakre- sie dokumentu przed wywołaniem [anURL bookmarkDataWithOptions]: Podczas tworzenia instancji NSData, ScopedBookmarkAgent dodaje do tego pliku coś (np. tag, prawdopodobnie rozszerzony atrybut pliku).

Jeśli zapisujesz dane (tj. Adresy URL zakładek) do tego pliku atomowo, w rzeczywistości nie są one zapisywane bezpośrednio do pliku, ale najpierw do pliku tymczasowego, którego nazwa została zmieniona, jeśli operacja zapisu zakończyła się pomyślnie. Wydaje się, że znacznik, który został dodany do (pustego, ale istniejącego) pliku, który będzie zawierał zakładki, gubi się podczas tego procesu zapisywania do pliku tymczasowego, a następnie zmieniania jego nazwy (a przez to prawdopodobnie usuwania oryginalnego, pustego pliku) .

Przy okazji: nie powinno być konieczne tworzenie zakładek o zasięgu aplikacji przed przekazaniem odpowiednich adresów URL do pliku xml zawierającego zakładki z zakresem dokumentu.

Dodatek: nazwa com.apple.security.files.bookmarks.collection-scope została zmieniona na com.apple.security.files.bookmarks.document-scope w wersji 10.7.4.

+0

Dzięki x1000. Ta myśl nigdy nie przyszła mi do głowy. Odnośnie zmienionego klucza uprawnień, czy możesz podać referencję? W dokumentacji nadal jest napisane "zakres zbierania". – Dov

+1

Zmiana nazwy uprawnienia jest wymieniona w tabeli 3-4 dokumentu [Entitlement Key Reference] (https://developer.apple.com/library/mac/#documentation/Miscellaneous/Reference/EntitlementKeyReference/EnablingAppSandbox/EnablingAppSandbox.html#//apple_ref/doc/uid/TP40011195-CH4-SW18). – Tim

+0

@Tim Wspomniałeś, że "konieczne jest posiadanie istniejącego (ale pustego) pliku, który będzie zawierać zakładki o zasięgu dokumentu". Jak należy znać lokalizację, w której użytkownik po raz pierwszy zapisze nowy dokument. Co więcej, w jaki sposób można utworzyć pusty plik w jakimś miejscu z piaskownicą, a NSSavePanel nie pojawia się w obrazie? – AmaltasCoder

Powiązane problemy