如何获取图片、音频、视频类UTType对应的全部扩展名字符串?
UTType获取图片/音频/视频全量扩展名解决方案
问题原因
原有实现仅获取了UTI对应的首选扩展名,无法拿到jpg、qt这类别名扩展名;且手动枚举UTI存在类型遗漏,还会出现重复值。
实现方案
iOS 14+/macOS 11+ 现代API实现
使用系统自带的UniformTypeIdentifiers框架,直接遍历根UTI的所有子类型,收集全量扩展名:
import UniformTypeIdentifiers var allMediaExtensions = Set<String>() // 收集所有图片类扩展名 if let imageTypes = UTType.types(tag: nil, tagClass: .filenameExtension, conformingTo: .image) { imageTypes.forEach { utType in guard let exts = utType.tags[.filenameExtension] else { return } allMediaExtensions.formUnion(exts.map { $0.lowercased() }) } } // 收集所有音频类扩展名 if let audioTypes = UTType.types(tag: nil, tagClass: .filenameExtension, conformingTo: .audio) { audioTypes.forEach { utType in guard let exts = utType.tags[.filenameExtension] else { return } allMediaExtensions.formUnion(exts.map { $0.lowercased() }) } } // 收集所有视频类扩展名 if let videoTypes = UTType.types(tag: nil, tagClass: .filenameExtension, conformingTo: .movie) { videoTypes.forEach { utType in guard let exts = utType.tags[.filenameExtension] else { return } allMediaExtensions.formUnion(exts.map { $0.lowercased() }) } } // 最终可用的全量扩展名数组 let mediaExtensionList = Array(allMediaExtensions)
兼容iOS 13及更低版本实现
基于CoreServices框架实现全量扩展名获取:
import CoreServices func getAllExtensions(for uti: CFString) -> [String] { let extensions = UTTypeCopyAllTagsWithClass(uti, kUTTagClassFilenameExtension)?.takeRetainedValue() as? [String] ?? [] return extensions.map { $0.lowercased() } } var allMediaExtensions = Set<String>() let rootUTIs: [CFString] = [kUTTypeImage, kUTTypeAudio, kUTTypeMovie] rootUTIs.forEach { rootUTI in guard let utis = UTTypeCreateAllIdentifiersForTagClass(kUTTagClassFilenameExtension, nil, rootUTI)?.takeRetainedValue() as? [CFString] else { return } utis.forEach { uti in allMediaExtensions.formUnion(getAllExtensions(for: uti)) } } // 最终可用的全量扩展名数组 let mediaExtensionList = Array(allMediaExtensions)
更准确的文件类型判断方案
如果仅需要判断文件是否属于图片/音频/视频类,无需对比扩展名,直接校验文件UTI兼容性即可,准确率更高:
// 现代API判断是否为图片 func isImageFile(url: URL) -> Bool { guard let fileUTI = try? url.resourceValues(forKeys: [.typeIdentifierKey]).typeIdentifier, let utType = UTType(fileUTI) else { return false } return utType.conforms(to: .image) } // 兼容旧版本API判断是否为图片 func isImageFileCompat(url: URL) -> Bool { guard let fileUTI = try? url.resourceValues(forKeys: [.typeIdentifierKey]).typeIdentifier else { return false } return UTTypeConformsTo(fileUTI as CFString, kUTTypeImage as CFString) }
按照相同逻辑可自行实现音频、视频的判断方法。
内容的提问来源于stack exchange,提问作者Lance Samaria
相关产品推荐
相关产品推荐

