Skip to content

Instantly share code, notes, and snippets.

@amosavian
Created September 29, 2017 20:01
Show Gist options
  • Save amosavian/437474fbe495a69996db8033924bd592 to your computer and use it in GitHub Desktop.
Save amosavian/437474fbe495a69996db8033924bd592 to your computer and use it in GitHub Desktop.
//
// UnformIdentifier.swift
// ExtDownloader
//
// Created by Amir Abbas on 7/6/1396 AP.
// Copyright © 1396 AP Mousavian. All rights reserved.
//
import Foundation
import MobileCoreServices
public struct UniformIdentifier: RawRepresentable, ExpressibleByStringLiteral, CustomStringConvertible {
public var rawValue: String
public init(rawValue: String) {
self.rawValue = rawValue
}
public init(stringLiteral value: String) {
self.rawValue = value
}
public init(mime: String) {
let uti: String
if let utiu = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mime as CFString, nil)?.takeRetainedValue() {
uti = utiu as String
} else {
uti = UniformIdentifier.data.rawValue
}
let utid = uti.hasPrefix("dyn.") ? UniformIdentifier.data.rawValue : uti
self.rawValue = utid
}
public init(fileExtension: String) {
let uti: String
if let utiu = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension as CFString, nil)?.takeRetainedValue() {
uti = utiu as String
} else {
uti = UniformIdentifier.data.rawValue
}
let utid = uti.hasPrefix("dyn.") ? UniformIdentifier.data.rawValue : uti
self.rawValue = utid
}
public init(url: URL) {
let isDirectory = (try? url.resourceValues(forKeys: [.isDirectoryKey]))?.isDirectory ?? false
let isSymLink = (try? url.resourceValues(forKeys: [.isSymbolicLinkKey]))?.isSymbolicLink ?? false
if isDirectory {
self.init(rawValue: UniformIdentifier.directory.rawValue)
} else if isSymLink {
self.init(rawValue: UniformIdentifier.symLink.rawValue)
} else {
self.init(fileExtension: url.pathExtension)
}
}
public init(filePath: String) {
let url = URL(fileURLWithPath: filePath)
self.init(url: url)
}
public func conformsTo(_ parrentUTI: UniformIdentifier) -> Bool {
return UTTypeConformsTo(self.rawValue as CFString, parrentUTI.rawValue as CFString)
}
public var preferredExtension: String? {
let uti = UTTypeCopyPreferredTagWithClass(self.rawValue as CFString, kUTTagClassFilenameExtension)?.takeRetainedValue()
return (uti as String?)
}
public var preferredExtensionWithHeirarchy: String? {
if let ext = self.preferredExtension {
return ext
}
let conforms = self.declaration.conformsTo
for conform in conforms {
if let ext = conform.preferredExtension {
return ext
}
}
return nil
}
public var preferredExtension3Letter: String? {
let ext = preferredExtension
if let ext = ext, ext.count <= 3 {
return ext
} else {
return suitableExtensions.filter({ $0.count <= 3 }).first ?? ext
}
}
public var suitableExtensions: [String] {
let exts = UTTypeCopyAllTagsWithClass(self.rawValue as CFString, kUTTagClassFilenameExtension)?.takeRetainedValue() as NSArray?
return exts as? [String] ?? []
}
public var preferredMime: String {
let mime: String
if let mimeu = UTTypeCopyPreferredTagWithClass(self.rawValue as CFString, kUTTagClassMIMEType)?.takeRetainedValue() {
mime = mimeu as String
} else {
mime = "application/octet-stream"
}
return mime
}
public var allMimes: [String] {
let exts = UTTypeCopyAllTagsWithClass(self.rawValue as CFString, kUTTagClassMIMEType)?.takeRetainedValue() as NSArray?
return exts as? [String] ?? []
}
public var description: String {
let desc: String
if let descu = UTTypeCopyDescription(self.rawValue as CFString)?.takeRetainedValue() {
desc = descu as String
} else {
if let lastC = self.rawValue.components(separatedBy: ".").last {
desc = lastC + " File"
} else {
desc = "File"
}
}
return desc
}
static func ~=(lhs: UniformIdentifier, rhs: UniformIdentifier) -> Bool {
return rhs.conformsTo(lhs)
}
}
extension UniformIdentifier {
// MARK: - Declaration
public struct Declaration: CustomStringConvertible, CustomDebugStringConvertible {
fileprivate let raw: [AnyHashable: Any]
public var exportedTypeDeclarations: [Declaration] {
return (raw[kUTExportedTypeDeclarationsKey as AnyHashable] as? [[AnyHashable: Any]] ?? []).map { Declaration(declaration: $0) }
}
public var importedTypeDeclarations: [Declaration] {
return (raw[kUTImportedTypeDeclarationsKey as AnyHashable] as? [[AnyHashable: Any]] ?? []).map { Declaration(declaration: $0) }
}
public var identifier: String? {
return raw[kUTTypeIdentifierKey as AnyHashable] as? String
}
public var tagSpecification: [AnyHashable: Any] {
return raw[kUTTypeTagSpecificationKey as AnyHashable] as? [AnyHashable: Any] ?? [:]
}
public var conformsTo: [UniformIdentifier] {
switch raw[kUTTypeConformsToKey as AnyHashable] {
case let array as [String]:
return array.map { UniformIdentifier(rawValue: $0) }
case let string as String:
return [ UniformIdentifier(rawValue: string) ]
default:
return []
}
}
public var iconFile: String? {
return raw[kUTTypeIconFileKey as AnyHashable] as? String
}
public var referenceUrl: URL? {
if let reference = raw[kUTTypeReferenceURLKey as AnyHashable] as? String {
return URL(string: reference)
}
return nil
}
public var version: String? {
return raw[kUTTypeIconFileKey as AnyHashable] as? String
}
init(declaration: [AnyHashable: Any]) {
self.raw = declaration
}
public var description: String {
return raw.description
}
public var debugDescription: String {
return raw.debugDescription
}
}
public var declaration: Declaration {
return Declaration(declaration: UTTypeCopyDeclaration(self.rawValue as CFString)?.takeRetainedValue() as! [AnyHashable: Any]? ?? [:])
}
}
extension String {
init(_ value: UniformIdentifier) {
self = value.rawValue
}
}
extension UniformIdentifier {
///
public static let item = UniformIdentifier(rawValue: kUTTypeItem as String)
///
public static let content = UniformIdentifier(rawValue: kUTTypeContent as String)
///
public static let compositeContent = UniformIdentifier(rawValue: kUTTypeCompositeContent as String)
///
public static let message = UniformIdentifier(rawValue: kUTTypeMessage as String)
///
public static let contact = UniformIdentifier(rawValue: kUTTypeContact as String)
///
public static let archive = UniformIdentifier(rawValue: kUTTypeArchive as String)
///
public static let diskImage = UniformIdentifier(rawValue: kUTTypeDiskImage as String)
///
public static let data = UniformIdentifier(rawValue: kUTTypeData as String)
///
public static let directory = UniformIdentifier(rawValue: kUTTypeDirectory as String)
///
public static let resolvable = UniformIdentifier(rawValue: kUTTypeResolvable as String)
///
public static let symLink = UniformIdentifier(rawValue: kUTTypeSymLink as String)
///
public static let executable = UniformIdentifier(rawValue: kUTTypeExecutable as String)
///
public static let mountPoint = UniformIdentifier(rawValue: kUTTypeMountPoint as String)
///
public static let aliasFile = UniformIdentifier(rawValue: kUTTypeAliasFile as String)
///
public static let aliasRecord = UniformIdentifier(rawValue: kUTTypeAliasRecord as String)
///
public static let urlBookmarkData = UniformIdentifier(rawValue: kUTTypeURLBookmarkData as String)
///
public static let url = UniformIdentifier(rawValue: kUTTypeURL as String)
///
public static let fileURL = UniformIdentifier(rawValue: kUTTypeFileURL as String)
///
public static let text = UniformIdentifier(rawValue: kUTTypeText as String)
///
public static let plainText = UniformIdentifier(rawValue: kUTTypePlainText as String)
///
public static let utf8PlainText = UniformIdentifier(rawValue: kUTTypeUTF8PlainText as String)
///
public static let utf16ExternalPlainText = UniformIdentifier(rawValue: kUTTypeUTF16ExternalPlainText as String)
///
public static let utf16PlainText = UniformIdentifier(rawValue: kUTTypeUTF16PlainText as String)
///
public static let delimitedText = UniformIdentifier(rawValue: kUTTypeDelimitedText as String)
///
public static let commaSeparatedText = UniformIdentifier(rawValue: kUTTypeCommaSeparatedText as String)
///
public static let tabSeparatedText = UniformIdentifier(rawValue: kUTTypeTabSeparatedText as String)
///
public static let utf8TabSeparatedText = UniformIdentifier(rawValue: kUTTypeUTF8TabSeparatedText as String)
///
public static let rtf = UniformIdentifier(rawValue: kUTTypeRTF as String)
///
public static let html = UniformIdentifier(rawValue: kUTTypeHTML as String)
///
public static let xml = UniformIdentifier(rawValue: kUTTypeXML as String)
///
public static let sourceCode = UniformIdentifier(rawValue: kUTTypeSourceCode as String)
///
public static let assemblyLanguageSource = UniformIdentifier(rawValue: kUTTypeAssemblyLanguageSource as String)
///
public static let cSource = UniformIdentifier(rawValue: kUTTypeCSource as String)
///
public static let objectiveCSource = UniformIdentifier(rawValue: kUTTypeObjectiveCSource as String)
///
@available(iOS 9.0, *)
public static let swiftSource = UniformIdentifier(rawValue: kUTTypeSwiftSource as String)
///
public static let cPlusPlusSource = UniformIdentifier(rawValue: kUTTypeCPlusPlusSource as String)
///
public static let objectiveCPlusPlusSource = UniformIdentifier(rawValue: kUTTypeObjectiveCPlusPlusSource as String)
///
public static let cHeader = UniformIdentifier(rawValue: kUTTypeCHeader as String)
///
public static let cPlusPlusHeader = UniformIdentifier(rawValue: kUTTypeCPlusPlusHeader as String)
///
public static let javaSource = UniformIdentifier(rawValue: kUTTypeJavaSource as String)
///
public static let script = UniformIdentifier(rawValue: kUTTypeScript as String)
///
public static let appleScript = UniformIdentifier(rawValue: kUTTypeAppleScript as String)
///
public static let osaScript = UniformIdentifier(rawValue: kUTTypeOSAScript as String)
///
public static let osaScriptBundle = UniformIdentifier(rawValue: kUTTypeOSAScriptBundle as String)
///
public static let javaScript = UniformIdentifier(rawValue: kUTTypeJavaScript as String)
///
public static let shellScript = UniformIdentifier(rawValue: kUTTypeShellScript as String)
///
public static let perlScript = UniformIdentifier(rawValue: kUTTypePerlScript as String)
///
public static let pythonScript = UniformIdentifier(rawValue: kUTTypePythonScript as String)
///
public static let rubyScript = UniformIdentifier(rawValue: kUTTypeRubyScript as String)
///
public static let phpScript = UniformIdentifier(rawValue: kUTTypePHPScript as String)
///
public static let json = UniformIdentifier(rawValue: kUTTypeJSON as String)
///
public static let propertyList = UniformIdentifier(rawValue: kUTTypePropertyList as String)
///
public static let xmlPropertyList = UniformIdentifier(rawValue: kUTTypeXMLPropertyList as String)
///
public static let binaryPropertyList = UniformIdentifier(rawValue: kUTTypeBinaryPropertyList as String)
///
public static let pdf = UniformIdentifier(rawValue: kUTTypePDF as String)
///
public static let rtfd = UniformIdentifier(rawValue: kUTTypeRTFD as String)
///
public static let flatRTFD = UniformIdentifier(rawValue: kUTTypeFlatRTFD as String)
///
public static let txnTextAndMultimediaData = UniformIdentifier(rawValue: kUTTypeTXNTextAndMultimediaData as String)
///
public static let webArchive = UniformIdentifier(rawValue: kUTTypeWebArchive as String)
///
public static let image = UniformIdentifier(rawValue: kUTTypeImage as String)
///
public static let jpeg = UniformIdentifier(rawValue: kUTTypeJPEG as String)
///
public static let jpeg2000 = UniformIdentifier(rawValue: kUTTypeJPEG2000 as String)
///
public static let tiff = UniformIdentifier(rawValue: kUTTypeTIFF as String)
///
public static let pict = UniformIdentifier(rawValue: kUTTypePICT as String)
///
public static let gif = UniformIdentifier(rawValue: kUTTypeGIF as String)
///
public static let png = UniformIdentifier(rawValue: kUTTypePNG as String)
///
public static let quickTimeImage = UniformIdentifier(rawValue: kUTTypeQuickTimeImage as String)
///
public static let appleICNS = UniformIdentifier(rawValue: kUTTypeAppleICNS as String)
///
public static let bmp = UniformIdentifier(rawValue: kUTTypeBMP as String)
///
public static let ico = UniformIdentifier(rawValue: kUTTypeICO as String)
///
public static let rawImage = UniformIdentifier(rawValue: kUTTypeRawImage as String)
///
public static let scalableVectorGraphics = UniformIdentifier(rawValue: kUTTypeScalableVectorGraphics as String)
///
public static let svg = UniformIdentifier(rawValue: kUTTypeScalableVectorGraphics as String)
///
@available(iOS 9.1, *)
public static let LivePhoto = UniformIdentifier(rawValue: kUTTypeLivePhoto as String)
///
public static let audiovisualContent = UniformIdentifier(rawValue: kUTTypeAudiovisualContent as String)
///
public static let movie = UniformIdentifier(rawValue: kUTTypeMovie as String)
///
public static let video = UniformIdentifier(rawValue: kUTTypeVideo as String)
///
public static let audio = UniformIdentifier(rawValue: kUTTypeAudio as String)
///
public static let quickTimeMovie = UniformIdentifier(rawValue: kUTTypeQuickTimeMovie as String)
///
public static let mpeg = UniformIdentifier(rawValue: kUTTypeMPEG as String)
///
public static let mpeg2Video = UniformIdentifier(rawValue: kUTTypeMPEG2Video as String)
///
public static let mpeg2TransportStream = UniformIdentifier(rawValue: kUTTypeMPEG2TransportStream as String)
///
public static let mp3 = UniformIdentifier(rawValue: kUTTypeMP3 as String)
///
public static let mpeg4 = UniformIdentifier(rawValue: kUTTypeMPEG4 as String)
///
public static let mpeg4Audio = UniformIdentifier(rawValue: kUTTypeMPEG4Audio as String)
///
public static let appleProtectedMPEG4Audio = UniformIdentifier(rawValue: kUTTypeAppleProtectedMPEG4Audio as String)
///
public static let appleProtectedMPEG4Video = UniformIdentifier(rawValue: kUTTypeAppleProtectedMPEG4Video as String)
///
public static let aviMovie = UniformIdentifier(rawValue: kUTTypeAVIMovie as String)
///
public static let audioInterchangeFileFormat = UniformIdentifier(rawValue: kUTTypeAudioInterchangeFileFormat as String)
///
public static let waveformAudio = UniformIdentifier(rawValue: kUTTypeWaveformAudio as String)
///
public static let midiAudio = UniformIdentifier(rawValue: kUTTypeMIDIAudio as String)
///
public static let playlist = UniformIdentifier(rawValue: kUTTypePlaylist as String)
///
public static let m3uplaylist = UniformIdentifier(rawValue: kUTTypeM3UPlaylist as String)
///
public static let folder = UniformIdentifier(rawValue: kUTTypeFolder as String)
///
public static let volume = UniformIdentifier(rawValue: kUTTypeVolume as String)
///
public static let package = UniformIdentifier(rawValue: kUTTypePackage as String)
///
public static let bundle = UniformIdentifier(rawValue: kUTTypeBundle as String)
///
public static let pluginBundle = UniformIdentifier(rawValue: kUTTypePluginBundle as String)
///
public static let spotlightImporter = UniformIdentifier(rawValue: kUTTypeSpotlightImporter as String)
///
public static let quickLookGenerator = UniformIdentifier(rawValue: kUTTypeQuickLookGenerator as String)
///
public static let xpcService = UniformIdentifier(rawValue: kUTTypeXPCService as String)
///
public static let framework = UniformIdentifier(rawValue: kUTTypeFramework as String)
///
public static let application = UniformIdentifier(rawValue: kUTTypeApplication as String)
///
public static let applicationBundle = UniformIdentifier(rawValue: kUTTypeApplicationBundle as String)
///
public static let applicationFile = UniformIdentifier(rawValue: kUTTypeApplicationFile as String)
///
public static let unixExecutable = UniformIdentifier(rawValue: kUTTypeUnixExecutable as String)
///
public static let windowsExecutable = UniformIdentifier(rawValue: kUTTypeWindowsExecutable as String)
///
public static let javaClass = UniformIdentifier(rawValue: kUTTypeJavaClass as String)
///
public static let javaArchive = UniformIdentifier(rawValue: kUTTypeJavaArchive as String)
///
public static let systemPreferencesPane = UniformIdentifier(rawValue: kUTTypeSystemPreferencesPane as String)
///
public static let gnuZipArchive = UniformIdentifier(rawValue: kUTTypeGNUZipArchive as String)
///
public static let bzip2Archive = UniformIdentifier(rawValue: kUTTypeBzip2Archive as String)
///
public static let zipArchive = UniformIdentifier(rawValue: kUTTypeZipArchive as String)
///
public static let spreadsheet = UniformIdentifier(rawValue: kUTTypeSpreadsheet as String)
///
public static let presentation = UniformIdentifier(rawValue: kUTTypePresentation as String)
///
public static let database = UniformIdentifier(rawValue: kUTTypeDatabase as String)
///
public static let vCard = UniformIdentifier(rawValue: kUTTypeVCard as String)
///
public static let toDoItem = UniformIdentifier(rawValue: kUTTypeToDoItem as String)
///
public static let calendarEvent = UniformIdentifier(rawValue: kUTTypeCalendarEvent as String)
///
public static let emailMessage = UniformIdentifier(rawValue: kUTTypeEmailMessage as String)
///
public static let internetLocation = UniformIdentifier(rawValue: kUTTypeInternetLocation as String)
///
public static let inkText = UniformIdentifier(rawValue: kUTTypeInkText as String)
///
public static let font = UniformIdentifier(rawValue: kUTTypeFont as String)
///
public static let bookmark = UniformIdentifier(rawValue: kUTTypeBookmark as String)
///
public static let threeDContent = UniformIdentifier(rawValue: kUTType3DContent as String)
///
public static let pkcs12 = UniformIdentifier(rawValue: kUTTypePKCS12 as String)
///
public static let x509Certificate = UniformIdentifier(rawValue: kUTTypeX509Certificate as String)
///
public static let electronicPublication = UniformIdentifier(rawValue: kUTTypeElectronicPublication as String)
///
public static let log = UniformIdentifier(rawValue: kUTTypeLog as String)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment