如何在SwiftUI文档类应用中强制触发「另存为」弹窗?
解决macOS文档编辑后保存触发「另存为」的问题
核心思路
当打开的是.l1格式文件时,通过文档类的方法拦截常规保存操作,强制触发「另存为」流程,同时默认指定.l2为保存格式。
具体实现步骤
- 记录原始文件格式
在TwoLineDocument类中添加属性,存储文档打开时的原始格式:
class TwoLineDocument: FileDocument { private var originalFileType: String? // 其他已有属性... }
在读取文件的初始化方法中,设置该属性:
init(configuration: ReadConfiguration) throws { // 原有读取JSON内容的逻辑... // 获取原始文件后缀 if let fileURL = configuration.fileURL { originalFileType = fileURL.pathExtension.lowercased() } try super.init(configuration: configuration) }
- 拦截常规保存操作
重写canSave(to:for:)方法,当原始格式为.l1且是常规保存(Command+S)时,返回false,触发系统的「另存为」流程:
override func canSave(to url: URL, for saveOperation: UIDocument.SaveOperation) -> Bool { // 原始是.l1文件,且是常规保存,拒绝直接保存 if saveOperation == .normal, originalFileType == "l1" { return false } return super.canSave(to: url, for: saveOperation) }
- 默认指定.l2保存格式
重写makeConfiguration(for:)方法,在「另存为」时默认选中.l2格式:
override func makeConfiguration(for saveOperation: UIDocument.SaveOperation) -> UIDocumentConfiguration { let config = super.makeConfiguration(for: saveOperation) // 针对.l1转存场景,默认设置为.l2格式 if saveOperation == .asCopy, originalFileType == "l1" { // 替换成你在Info.plist中注册的.l2格式对应的UTI config.defaultType = UTType("com.yourdomain.l2")! } return config }
- 验证UTI配置
确保Info.plist中已正确注册.l1和.l2的UTI,示例配置:
<key>CFBundleDocumentTypes</key> <array> <dict> <key>CFBundleTypeName</key> <string>Two Line Document</string> <key>CFBundleTypeExtensions</key> <array> <string>l2</string> </array> <key>LSItemContentTypes</key> <array> <string>com.yourdomain.l2</string> </array> </dict> <dict> <key>CFBundleTypeName</key> <string>One Line Document</string> <key>CFBundleTypeExtensions</key> <array> <string>l1</string> </array> <key>LSItemContentTypes</key> <array> <string>com.yourdomain.l1</string> </array> </dict> </array> <key>UTExportedTypeDeclarations</key> <array> <dict> <key>UTTypeIdentifier</key> <string>com.yourdomain.l1</string> <key>UTTypeDescription</key> <string>One Line JSON Document</string> <key>UTTypeTagSpecification</key> <dict> <key>public.filename-extension</key> <array> <string>l1</string> </array> </dict> </dict> <dict> <key>UTTypeIdentifier</key> <string>com.yourdomain.l2</string> <key>UTTypeDescription</key> <string>Two Line JSON Document</string> <key>UTTypeTagSpecification</key> <dict> <key>public.filename-extension</key> <array> <string>l2</string> </array> </dict> </dict> </array>
效果验证
打开.l1文件编辑后按Command+S,系统会自动弹出「另存为」对话框,默认格式为.l2,无法直接覆盖原.l1文件,符合需求。
内容的提问来源于stack exchange,提问作者Sweeper
相关产品推荐
相关产品推荐

