Как узнать, какой тип файла был выбран в NSSavePanel?

Я пишу приложение в системе Mavericks. Я звоню NSSavePanel, чтобы сохранить файл. Я могу дать панели NSArray UTI для использования в качестве возможных типов сохранения, и (я полагаю) панель автоматически сгенерирует вспомогательное представление выходного типа. Во время блока завершения панели я могу использовать свойство «URL» панели, чтобы заставить файл (возможно, создать и) записать. Но, похоже, нет свойства, указывающего, какой тип вывода был выбран.

Должен ли я смотреть на расширение файла URL? Это потому, что есть возможность разрешить произвольное именование расширений? (У меня эта опция не включена здесь.)

Также: мой NSArray UTI представляет собой случайный тип, за которым следует фиксированный тип. В настоящее время я добавляю фиксированный тип, только если он не равен случайному типу. Произойдет ли сбой панели, если у меня будет один и тот же UTI несколько раз, или она разрушит дубликаты? Если не произойдет сбой, я могу сэкономить время с помощью безусловного добавления.


person CTMacUser    schedule 17.08.2014    source источник


Ответы (1)


По вопросу также: я выполнил безусловное добавление, и ничего не вышло из строя. Так что я думаю, что код Apple сворачивает дубликаты.

По моему мнению, панель не создает вспомогательное представление для выбора из нескольких UTI. (Эквивалентное действие для приложения, ориентированного на NSDocument, делает.) Панель выбирает начальное (не очень) секретное расширение для нового файла на основе массива UTI. Если вы добавите расширение, и оно либо находится в списке UTI, либо включено произвольное именование расширений, панель разрешит это. В противном случае вы получите предупреждение о неправильном расширении. Я упомянул случайный тип и фиксированный тип; В 99% случаев пользователю нужен случайный тип, он выбирается первым, и я не возражаю против фиксированного типа, требующего, чтобы опытный пользователь активировал его (путем добавления его расширения).

Похоже, мне нужно использовать расширение файла URL для ввода моего файла. У меня есть только два доступных типа: случайный тип — это необработанные данные, а фиксированный тип — тот, который я всегда могу сгенерировать. И фиксированный тип имеет простое расширение, поэтому я могу различать, какой блок данных мне нужно получить. Я не включаю произвольное именование расширений, потому что ничего не могу сделать с дополнительными типами.

/*!
    @brief Action to save a copy of the currently displayed resource.
    @param sender The object that sent this message.
 */
- (IBAction)saveDocumentTo:(id)sender
{
    NSSavePanel * const       panel = [NSSavePanel savePanel];
    WebDataSource * const    source = self.webView.mainFrame.dataSource;
    NSURLResponse * const  response = source.response;
    NSArray * const       fileTypes = (__bridge_transfer NSArray *)UTTypeCreateAllIdentifiersForTag(kUTTagClassMIMEType, (__bridge CFStringRef)response.MIMEType, NULL);

    panel.allowedFileTypes = [fileTypes arrayByAddingObject:(__bridge NSString *)kUTTypeWebArchive];
    panel.nameFieldStringValue = response.suggestedFilename;
    panel.canSelectHiddenExtension = YES;

    [panel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result){
        if (result == NSFileHandlingPanelOKButton) {
            NSError  *error = nil;

            if (![([fileTypes firstObjectCommonWithArray:(__bridge_transfer NSArray *)UTTypeCreateAllIdentifiersForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)panel.URL.pathExtension, NULL)] ? source.data : source.webArchive.data) writeToURL:panel.URL options:NSDataWritingAtomic error:&error]) {
                [self performSelector:@selector(showError:) withObject:error afterDelay:0.0];
            }
        }
    }];
}

Вы должны в основном следить за тем, что я делаю. Объект fileTypes получает массив UTI, соответствующих MIME-типу ресурса. Я даю панели этот массив с добавленным фиксированным типом (веб-архив). В этом последнем if я генерирую список UTI из расширения файла URL-адреса назначения, смотрю, перекрывается ли хотя бы один UTI в массивах MIME и Extension, выбираю необработанные исходные данные, если есть перекрытие, или создаю данные веб-архива, если это не так. 't (т. е. к URL-адресу добавлено расширение веб-архива) и записывает эти данные на диск.

Обратите внимание, что если исходные данные были самим веб-архивом, они будут соответствовать исходному массиву UTI, и его данные будут сброшены напрямую. У меня изначально было по-другому; загруженный веб-архив будет сохранен как архив архива. Это увеличивает размер файла мусором, который мешает загрузке, если вы попытаетесь загрузить второй архив (чтобы попробовать третий раунд). Теперь они идентичны, кроме дат создания.

person CTMacUser    schedule 17.08.2014