1

我正在 Mavericks 系统上编写应用程序。我正在调用 NSSavePanel 来保存文件。我可以给面板一个 NSArray 的 UTI 以用作可能的保存类型,并且(我猜)面板将自动生成一个输出类型的附件视图。在面板完成块期间,我可以使用面板的“URL”属性来获取(可能创建和)写入文件。但是似乎没有属性可以指示选择了哪种输出类型。

我应该查看 URL 的文件扩展名吗?这是因为有一个允许自由扩展命名的选项吗?(我这里没有打开该选项。)

另外:我的 NSArray 的 UTI 是一个随机类型,后跟一个固定类型。我目前仅在不等于随机类型时才添加固定类型。如果我多次使用相同的 UTI,面板会崩溃,还是会折叠重复项?如果它不会崩溃,那么我可以通过无条件追加来节省时间。

4

1 回答 1

0

对于另一个问题:我做了一个无条件的追加,似乎没有什么崩溃。所以我猜苹果的代码确实会折叠重复项。

我的猜测是:面板不会创建附件视图以在多个 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对象获取与资源的 MIME 类型匹配的 UTI 数组。我给面板添加了固定类型(Web 存档)的数组。最后if,我从目标 URL 的文件扩展名生成 UTI 列表,查看 MIME 和扩展数组中是否至少有一个 UTI 重叠,如果有重叠则选择原始源数据,如果没有则创建 Web 存档数据t(即 URL 具有附加的 Web Archive 的扩展名),并将该数据写入磁盘。

请注意,如果原始数据本身是 Web 存档,它将匹配原始 UTI 数组并直接转储其数据。我原本是相反的。加载的 Web 存档将保存为存档的存档。如果您尝试加载第二个存档(尝试第三轮),这会使文件大小膨胀,并且会导致加载混乱。现在除了创建日期之外它们是相同的。

于 2014-08-17T23:38:38.120 回答