При разрешении NSURL из закладки с защищенной областью, если пользователь переименовал или переместил этот файл или папку, закладка будет устаревать. В документе Apple говорится об этом:
isStale
При возврате, если ДА, данные закладки устаревают. Ваше приложение должно создать новую закладку с использованием возвращаемого URL-адреса и использовать ее вместо любые сохраненные копии существующей закладки.
К сожалению, это редко работает для меня. Он может работать в 5% случаев. Попытка создать новую закладку с использованием возвращаемого URL приводит к ошибке, код 256 и просмотр в консоли показывает сообщение из sandboxd, в котором говорится о запрете чтения файлов на обновленном URL.
Примечание Если регенерация закладки работает, она работает только при первом восстановлении. Кажется, никогда не работает, если папка/файл будет перемещаться/переименовываться снова.
Как я изначально создаю и сохраняю закладку
-(IBAction)bookmarkFolder:(id)sender {
_openPanel = [NSOpenPanel openPanel];
_openPanel.canChooseFiles = NO;
_openPanel.canChooseDirectories = YES;
_openPanel.canCreateDirectories = YES;
[_openPanel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) {
if (_openPanel.URL != nil) {
NSError *error;
NSData *bookmark = [_openPanel.URL bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
includingResourceValuesForKeys:nil
relativeToURL:nil
error:&error];
if (error != nil) {
NSLog(@"Error bookmarking selected URL: %@", error);
return;
}
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:bookmark forKey:@"bookmark"];
}
}];
}
Код, разрешающий закладку
-(void)resolveStoredBookmark {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSData *bookmark = [userDefaults objectForKey:@"bookmark"];
if (bookmark == nil) {
NSLog(@"No bookmark stored");
return;
}
BOOL isStale;
NSError *error;
NSURL *url = [NSURL URLByResolvingBookmarkData:bookmark
options:NSURLBookmarkResolutionWithSecurityScope
relativeToURL:nil
bookmarkDataIsStale:&isStale
error:&error];
if (error != nil) {
NSLog(@"Error resolving URL from bookmark: %@", error);
return;
} else if (isStale) {
if ([url startAccessingSecurityScopedResource]) {
NSLog(@"Attempting to renew bookmark for %@", url);
// NOTE: This is the bit that fails, a 256 error is
// returned due to a deny file-read-data from sandboxd
bookmark = [url bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
includingResourceValuesForKeys:nil
relativeToURL:nil
error:&error];
[url stopAccessingSecurityScopedResource];
if (error != nil) {
NSLog(@"Failed to renew bookmark: %@", error);
return;
}
[userDefaults setObject:bookmark forKey:@"bookmark"];
NSLog(@"Bookmark renewed, yay.");
} else {
NSLog(@"Could not start using the bookmarked url");
}
} else {
NSLog(@"Bookmarked url resolved successfully!");
[url startAccessingSecurityScopedResource];
NSArray *contents = [NSFileManager.new contentsOfDirectoryAtPath:url.path error:&error];
[url stopAccessingSecurityScopedResource];
if (error != nil) {
NSLog(@"Error reading contents of bookmarked folder: %@", error);
return;
}
NSLog(@"Contents of bookmarked folder: %@", contents);
}
}
Когда закладка устарела, результирующий разрешенный URL указывает на правильное местоположение, я просто не могу получить доступ к файлу, несмотря на то, что [url startAccessingSecurityScopedResource] возвращает YES.
Возможно, я неверно истолковал документацию относительно устаревших закладок, но я надеюсь, что я просто делаю что-то глупое. Появление NSOpenPanel каждый раз, когда файл/папка с закладками переименовывается или перемещается, мой единственный вариант на данный момент кажется смешным.
Я должен добавить, что у меня есть com.apple.security.files.bookmarks.app-scope, com.apple.security.files.user-selected.read-write и com.apple.security.app-sandbox все установите в true в моем файле прав.