startAccessingSecurityScopedResource никогда не возвращает успех

Я разрабатываю изолированное приложение Mac App Store, которое спрашивает пользователя, где сохранять файлы, которые он загружает из других источников. У меня есть этот код, чтобы получить папку от пользователя (удалив некоторую проверку ошибок):

NSOpenPanel* openPanel = [NSOpenPanel openPanel];
[openPanel setAllowsMultipleSelection:NO];
[openPanel setCanChooseDirectories:YES];
[openPanel setResolvesAliases:YES];
NSInteger result = [openPanel runModal];
NSArray* urls = [openPanel URLs];
NSURL* folderURL = [urls objectAtIndex:0];
NSError* error;
NSData* bookmakeData = [folderURL bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
                           includingResourceValuesForKeys:nil
                                            relativeToURL:nil
                                                    error:&error];
_saveFolderBookmark = bookmakeData;

и когда приходит время переместить файл в эту папку, у меня есть этот код:

BOOL isStale;
NSError* error;
NSURL* saveFolder = [NSURL URLByResolvingBookmarkData:_saveFolderBookmark
                                              options:NSURLBookmarkCreationWithSecurityScope
                                        relativeToURL:nil
                                  bookmarkDataIsStale:&isStale
                                                error:&error];
BOOL success = [saveFolder startAccessingSecurityScopedResource];

// Move the file somewhere else
NSWorkspace* workspace = [NSWorkspace sharedWorkspace];
NSInteger operationTag;
BOOL copied = [workspace performFileOperation:NSWorkspaceMoveOperation
                                       source:[[self getDocumentsFolder] path]
                                  destination:[saveFolder path]
                                        files:[NSArray arrayWithObject:filename]
                                          tag:&operationTag];
[saveFolder stopAccessingSecurityScopedResource];

Для перечисления достаточно много кода, чтобы сказать, что startAccessingSecurityScopedResource никогда не возвращает мне успех, либо сразу после получения ULR из NSOpenPanel, либо при более позднем запуске с сохранением данных закладок в NSUserDefaults.

В файле прав, среди прочего, у меня есть:

<key>com.apple.security.files.bookmarks.app-scope</key>
<true/>

Что-то не так с этим кодом?


person Gary Makin    schedule 05.06.2012    source источник
comment
Видите ли вы какие-либо сообщения консоли? Кроме того, дважды проверьте подпись кода, чтобы убедиться, что она настроена правильно.   -  person gaige    schedule 05.06.2012
comment
В вашем примере непонятно, откуда берется массив urls после завершения открытой панели.   -  person gaige    schedule 05.06.2012
comment
Мне удалось отредактировать строку получения URL-адресов, когда я удалил проверку ошибок. Я положил его обратно. В консоли нет сообщений вокруг строки, вызывающей startAccessingSecurityScopedResource.   -  person Gary Makin    schedule 05.06.2012


Ответы (2)


Это очень легко. Вы разрешаете с помощью NSURLBookmarkCreationWithSecurityScope вместо NSURLBookmarkResolutionWithSecurityScope. Просто измените эту строку, и она должна работать.

(Он может не работать в том же сеансе, где вы создаете закладку, когда у вас уже есть доступ к URL-адресу, потому что вы не должны вызывать его в этом случае. Но при более поздних запусках он должен, конечно, потому что это весь смысл.)

person abarnert    schedule 05.06.2012
comment
Очень очевидно теперь, когда на это указали. Заставляет задуматься, почему существуют две разные константы. Спасибо! - person Gary Makin; 06.06.2012
comment
Если посмотреть на историю, то все понятно. Исходный набор флагов BookmarkCreation и BookmarkResolution в версии 10.6 не имел подходящих пар, поэтому они были полностью независимыми наборами значений битовой маски, и не было никакой возможности путаницы между, например, NSURLBookmarkCreationMinimalBookmark и NSURLBookmarkResolutionWithoutUI. Но было бы неплохо, если бы они добавили какой-то способ, чтобы компилятор предупреждал вас об этом, не так ли? - person abarnert; 06.06.2012

Правильное решение было дано выше, но я подумал, что добавлю еще одну возможность для тех, у кого есть тот же симптом (startAccessingSecurityScopedResource никогда не возвращается YES). Убедитесь, что вы используете фактический URL-адрес, возвращаемый Powerbox, который может (вероятно, будет) отличаться от URL-адреса фактического ресурса, к которому вы пытаетесь получить доступ. Например, Powerbox вернет URL-адрес пути, который вы использовали бы с startAccessingSecurityScopedResource для доступа к определенному файлу в этом каталоге.

person Demitri    schedule 08.09.2016