Как создать тип документа только для импорта в Какао? - PullRequest
6 голосов
/ 11 июня 2009

Мой тип приложения импортируется, но не сохраняется. Я добавил запись в типы документов и установил ее только для чтения, но это не дает нужного мне поведения при импорте. Вместо этого мое приложение просто откроет файл, и при сохранении исходный файл будет перезаписан в моем собственном формате файла.

Как настроить мой документ или типы документов, чтобы он создавался так, чтобы новый документ создавался с данными из исходного документа, а не с открываемым оригиналом?

Ответы [ 3 ]

13 голосов
/ 02 апреля 2013

1. Объявите типы файлов как типы документов

В вашем проекте XCode добавьте Тип документа для всех форматов файлов, поддерживаемых вашим приложением. Установите Роль каждого типа в соответствии со способностями вашего приложения:

  • Пометить типы файлов с возможностью чтения / записи как Editor ;
  • Пометить импорт файлов только как Просмотр .

Установите Class на тип документа, который вы хотите обрабатывать для каждого типа файла. Один класс документов может обрабатывать несколько типов файлов.

В приведенном ниже примере объявлены три типа файлов: font-pestle, otf и ttf. Первый, font-pestle, является родным форматом приложения. Этот тип имеет роль Editor .

Оставшиеся два формата, otf и ttf, могут быть импортированы, но не записаны приложением; таким образом они помечены как Просмотрщик .

Example Document Types

2. Дополнительные типы файлов в вашем подклассе NSDocument

При добавлении типов документов приложение автоматически разрешает пользователям открывать файлы указанных типов.

Вам необходимо добавить код обработки типов файлов в ваш класс документов. В идеальном случае добавьте код ветвления к методу 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 значение nil, вы говорите, что документ не связан ни с одним файлом на диске и должен рассматриваться как новый документ.

Чтобы разрешить автоматическое сохранение, реализуйте метод NSDocument autosavingFileType для возврата основного типа файла.

4 голосов
/ 16 июня 2009

Алекс, спасибо за ваш ответ, но я нашел способ, который мне нравится немного больше:

- (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)
    }
}

Таким образом, все еще можно использовать систему документов, предоставляемую Какао, вместо того, чтобы катать мою собственную.

Я также задокументировал решение здесь: http://www.cocoadev.com/index.pl?CFBundleTypeRole немного вниз по странице.

1 голос
/ 11 июня 2009

Я не верю, что функция импорта поддерживается по умолчанию в Какао. Когда пользователь нажимает кнопку «Открыть» на открытой панели, платформа вызывает openDocumentWithContentsOfURL:display:error: на NSDocumentController. Здесь система документов определяет, какой тип файла вы открываете, и обращается к файлу Info.plist, чтобы выяснить, какой подкласс NSDocument использовать для открытия документа.

Вы можете создать подкласс NSDocumentController и переопределить метод openDocumentWithContentsOfURL:display:error:, чтобы перехватывать типы файлов, которые следует импортировать, а не открывать. В своем подклассе NSDocument напишите новый инициализатор с именем, подобным initWithImportedContentsOfURL:type:error: (или что-то с лучшим именем :-)), чтобы создать новый документ без названия и прочитать содержимое импортированного файла.

...