对于另一个问题:我做了一个无条件的追加,似乎没有什么崩溃。所以我猜苹果的代码确实会折叠重复项。
我的猜测是:面板不会创建附件视图以在多个 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 存档将保存为存档的存档。如果您尝试加载第二个存档(尝试第三轮),这会使文件大小膨胀,并且会导致加载混乱。现在除了创建日期之外它们是相同的。