SwiftUI fileImporter的allowedContentTypes如何支持xcodeproj类型
解决方案
.xcodeproj属于包(Bundle)结构的文件,UniformTypeIdentifiers框架没有内置对应静态值,自行扩展UTType即可让.fileImporter正常识别该类型,步骤如下:
1. 扩展UTType定义Xcode项目类型
Xcode项目文件的官方统一类型标识符为com.apple.xcode.project,由于它是包结构而非单文件,需要声明其遵循.package类型:
import UniformTypeIdentifiers extension UTType { static let xcodeproj = UTType( exportedAs: "com.apple.xcode.project", conformingTo: .package ) }
如果不想硬编码类型标识符,也可以通过文件后缀初始化,效果一致:
extension UTType { static let xcodeproj = UTType(filenameExtension: "xcodeproj", conformingTo: .package)! }
2. 修正原有代码
原代码存在一处笔误:按钮文字中的projext应为project,替换后直接使用自定义的.xcodeproj类型即可,完整可运行代码如下:
import SwiftUI import UniformTypeIdentifiers extension UTType { static let xcodeproj = UTType( exportedAs: "com.apple.xcode.project", conformingTo: .package ) } struct ContentView: View { @State private var fileImporterIsPresented: Bool = false var body: some View { Button("Select your Xcode project") { fileImporterIsPresented = true } .fileImporter( isPresented: $fileImporterIsPresented, allowedContentTypes: [.xcodeproj], allowsMultipleSelection: false ) { result in switch result { case .success(let urls): guard let url = urls.first else { return } // 沙盒环境下需先获取安全访问权限再操作文件 if url.startAccessingSecurityScopedResource() { print(url.path) // 文件操作完成后停止访问 url.stopAccessingSecurityScopedResource() } case .failure(let error): print("File selection error: \(error.localizedDescription)") } } } }
注意事项
- 必须将xcodeproj类型的父类型设置为
.package,否则系统会将其识别为普通文件夹,无法在文件选择器中匹配到Xcode项目文件 - 如果需要同时支持选择Xcode工作区(.xcworkspace)文件,可按相同方式扩展,对应类型标识符为
com.apple.dt.workspace,同样遵循.package类型 - 开启App Sandbox的应用,拿到选中文件的URL后必须调用安全作用域方法获取访问权限,否则无法读取文件内容
内容的提问来源于stack exchange,提问作者swiftPunk
相关产品推荐
相关产品推荐

