Как мне создать тип документа, доступный только для импорта, в Cocoa?
-
13-09-2019 - |
Вопрос
Там есть тип файла, который мое приложение импортирует, но не сохраняет.Я добавил запись в типы документов и установил для нее режим только для чтения, но это не приводит к тому поведению импорта, которое я ищу.Вместо этого мое приложение просто откроет файл, и когда я сохраню исходный файл, он будет перезаписан в моем собственном формате.
Как настроить "Мой документ" или "типы документов", чтобы создать новый документ с данными из исходного документа вместо того, чтобы открывать оригинал?
Решение
1.Объявляйте типы файлов как Типы документов
В вашем проекте Xcode добавьте Тип документа для всех форматов файлов, поддерживаемых вашим приложением.Установите Роль каждого типа в соответствии с возможностями вашего приложения:
- Отметьте типы файлов, доступные для чтения / записи, как Редактор;
- Отметьте импортируемые только типы файлов как Зритель.
Установите Класс к типу документа, с которым вы хотите обрабатывать каждый тип файла.Один класс документа может обрабатывать несколько типов файлов.
В приведенном ниже примере объявлено три типа файлов:шрифт-пестик, otf и ttf.Первый, font-pestle, является собственным форматом приложения.У этого типа есть роль Редактор.
Остальные два формата, otf и ttf, могут быть импортированы, но не записаны приложением;таким образом , они помечены как Зритель.
2.Дополнительные типы файлов в вашем подклассе NSDocument
С добавлением типов документов приложение автоматически позволит пользователям открывать файлы указанных типов.
Вам нужно добавить код обработки типов файлов в ваш класс document.В идеальном случае добавьте код ветвления к readFromData:ofType:error:
способ:
- (BOOL)readFromData:(NSData*)someData ofType:(NSString*)typeName error:(NSError**)outError
{
if ([NSWorkspace.sharedWorkspace type:@"eu.miln.font-pestle" conformsToType:typeName] == YES)
{
// read native format
}
else if ([NSWorkspace.sharedWorkspace type:@"public.opentype-font" conformsToType:typeName] == YES)
{
// read import only format
// disassociate document from file; makes document "untitled"
self.fileURL = nil;
// associate with primary file type
self.fileType = @"eu.miln.font-pestle";
}
else // ...
}
В self.fileURL = nil;
это важно.Устанавливая fileURL равным нулю, вы говорите, что документ не связан ни с каким файлом на диске и должен рассматриваться как новый документ.
Чтобы разрешить автоматическое сохранение, реализуйте метод NSDocument autosavingFileType
чтобы вернуть основной тип файла.
Другие советы
Алекс, спасибо за твой ответ, но я нашел способ, который мне нравится немного больше:
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName
error:(NSError **)outError
{
*outError = nil;
if ([typeName isEqualToString:@"SomeReadOnlyType"])
{
// .. (load data here)
[self setFileURL:nil];
return result;
}
else
{
// .. (do whatever you do for other documents here)
}
}
Таким образом, по-прежнему возможно использовать систему документооборота, предоставляемую Cocoa, вместо того, чтобы создавать свою собственную.
Я также задокументировал решение здесь: http://www.cocoadev.com/index.pl?CFBundleTypeRole немного ниже по странице.
Я не верю, что функция импорта поддерживается в Cocoa по умолчанию.Когда пользователь нажимает кнопку Открыть на панели открыть, фреймворк вызывает openDocumentWithContentsOfURL:display:error:
на NSDocumentController
.Здесь система документооборота определяет, какой тип файла вы открываете, и консультируется с файлом Info.plist, чтобы определить, какой NSDocument
подкласс, используемый для открытия документа.
Вы могли бы создать подкласс NSDocumentController
и переопределить openDocumentWithContentsOfURL:display:error:
метод для перехвата типов файлов, которые следует импортировать, а не открывать.В вашем NSDocument
подкласс, напишите новый инициализатор с именем типа initWithImportedContentsOfURL:type:error:
(или что-нибудь с лучшим названием :-) ) чтобы создать новый документ без названия и прочитать содержимое импортированного файла.