Замените файл с помощью NSSavePanel в изолированном приложении
Я создаю NSSavePanel
используя этот код:
NSSavePanel *savePanel = [NSSavePanel savePanel];
savePanel.delegate = self;
savePanel.directoryURL = ...;
savePanel.nameFieldStringValue = ...;
[savePanel beginSheetModalForWindow:self.window
completionHandler:^(NSInteger returnCode) {
if (returnCode == NSFileHandlingPanelOKButton) {
// the completion handler
}
}];
Если на панели сохранения пользователь выбирает уже существующий файл, появляется окно с предупреждением "" ХХХ "уже существует. Вы хотите заменить его?".
Если пользователь нажимает кнопку "Заменить", в обработчике завершения старый файл удаляется с removeItemAtPath:error:
метод NSFileManager
, а затем создается новый файл (на самом деле: он создается во временном местоположении, а затем перемещается с использованием moveItemAtPath:toPath:error:
метод, но я думаю, что это просто деталь реализации):
if (returnCode == NSFileHandlingPanelOKButton) {
// overwrite the url, because if we are here is because the user has already
// expressed its willingness to overwrite the previous file
NSError *error = nil;
BOOL res = [[NSFileManager defaultManager] removeItemAtURL:savePanel.URL error:&error];
if (res) {
res = [[NSFileManager defaultManager] moveItemAtPath:tmpFilePath toPath:savePanel.URL error:&error];
}
// ...
}
В прошлом все всегда работало правильно. Однако сегодня я начал использовать Lion's Sandbox с правом "Чтение / запись".
С песочницей removeItemAtPath:error:
успешно, но следующее moveItemAtPath:toPath:error:
возвращает ошибку.
Это кажется разумным, потому что Powerbox дает мне права доступа (при чтении и записи) к файлу. Когда я удаляю этот файл, предоставленное мне право исчерпывается.
Правильно ли мое предположение?
Как я могу решить эту проблему?
2 ответа
Проблема в том, что после удаления файла ваши права на этот файл также исчезают. Вместо этого вам нужно перезаписать файл, например, используя [[NSFileManager defaultManager] createFileAtPath:contents:attributes:]
, Документация NSFileManager заявляет следующее для этого метода:
Если файл уже существует по пути, этот метод перезаписывает содержимое этого файла, если текущий процесс имеет соответствующие права для этого.
Используя методы из NSData
/NSMutableData
также может быть полезным.
Используйте [NSFileHandle fileHandleForWritingToURL:error:] с последующим writeData: вызовы для перезаписи существующего файла. Этот метод работает для меня в изолированном приложении. Для нового файла просто создайте его с помощью метода NSFileManager createFileAtPath:contents:attribute: (с содержимым, установленным в nil, если содержимое не помещается в память), а затем используйте NSFileHandle для записи данных.
Если вы хотите перезаписать изображение с использованием основной графики, см. NSSavePanel, CGImageDestinationFinalize и OS X sandbox