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

StackOverflow https://stackoverflow.com/questions/979647

  •  13-09-2019
  •  | 
  •  

Вопрос

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

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

Это было полезно?

Решение

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

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

  • Отметьте типы файлов, доступные для чтения / записи, как Редактор;
  • Отметьте импортируемые только типы файлов как Зритель.

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

В приведенном ниже примере объявлено три типа файлов:шрифт-пестик, otf и ttf.Первый, font-pestle, является собственным форматом приложения.У этого типа есть роль Редактор.

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

Example Document Types

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top