How to get All Extensions for UTType Image, Audio, and Video
Asked Answered
A

3

9

Is there a way to get All of the different UTType extension types as Strings? I need them specifically for images, audio, and video.

I followed this answer, but it doesn't give me all of the extensions

var types = [String]()

let utiTypes = [kUTTypeImage, kUTTypeMovie, kUTTypeVideo, kUTTypeMP3, kUTTypeAudio, kUTTypeQuickTimeMovie, kUTTypeMPEG, kUTTypeMPEG2Video, kUTTypeMPEG2TransportStream, kUTTypeMPEG4, kUTTypeMPEG4Audio, kUTTypeAppleProtectedMPEG4Audio, kUTTypeAppleProtectedMPEG4Video, kUTTypeAVIMovie, kUTTypeAudioInterchangeFileFormat, kUTTypeWaveformAudio, kUTTypeMIDIAudio, kUTTypeLivePhoto, kUTTypeTIFF, kUTTypeGIF, kUTTypeQuickTimeImage, kUTTypeAppleICNS]

for type in utiTypes {
            
    let str = String(type)
            
    guard let utiStr = fileExtension(for: str) else { continue }

    types.appent(utiStr)
}

dump(types)

The results are

15 elements // there are really 21 types
  - "jpeg"
  - "png"
  - "mov"
  - "mpg"
  - "m2v"
  - "ts"
  - "mp3"
  - "mp4"
  - "mp4"
  - "avi"
  - "aiff"
  - "wav"
  - "midi"
  - "tiff"
  - "gif"

The issue here is it doesn't return values like qt or jpg. For example I use the UIDocumentPickerViewController and when I select an image the returned url pathExtension is jpg not jpeg. If I wanted to know if the returned url was an image, and I compared its pathExtension to the types array above, it would say that it doesn't appear in the list.

Areca answered 24/11, 2021 at 20:2 Comment(2)
I can't actually reproduce your output in a playground. I don't even get "jpeg" or "png".Heisser
@Heisser that's strange? did you import MobileCoreServices?Areca
H
13

You can do:

import UniformTypeIdentifiers

let utiTypes = [UTType.image, .movie, .video, .mp3, .audio, .quickTimeMovie, .mpeg, .mpeg2Video, .mpeg2TransportStream, .mpeg4Movie, .mpeg4Audio, .appleProtectedMPEG4Audio, .appleProtectedMPEG4Video, .avi, .aiff, .wav, .midi, .livePhoto, .tiff, .gif, UTType("com.apple.quicktime-image"), .icns]

print(utiTypes.flatMap { $0?.tags[.filenameExtension] ?? [] })

There are 33 file extensions in total for the UTTypes that you have listed when I run this code in a playground. Note that some UTTypes you have listed have no file name extensions associated with them, probably because they are too "generic" (e.g. "image" and "video"). And some UTTypes have multiple file name extensions, and some may be the same with the file name extensions of other UTTypes.

There is no "jpg" or "png" in the output. To see them appear, you will have to use this list:

// I've also removed the types that have no file name extensions
let utiTypes = [
    UTType.jpeg,
    .png,
    .mp3,
    .quickTimeMovie,
    .mpeg,
    .mpeg2Video,
    .mpeg2TransportStream,
    .mpeg4Movie,
    .mpeg4Audio,
    .appleProtectedMPEG4Audio,
    .avi,
    .aiff,
    .wav,
    .midi,
    .tiff,
    .gif,
    UTType("com.apple.quicktime-image"),
    .icns
]

Using the above list, the output for me is:

jpeg
jpg
jpe
png
mp3
mpga
mov
qt
mpg
mpeg
mpe
m75
m15
m2v
ts
mp4
mpg4
mp4
mpg4
m4p
avi
vfw
aiff
aif
wav
wave
bwf
midi
mid
smf
kar
tiff
tif
gif
qtif
qti
icns

Also note that if you want to get the UTType from a file name extension, you can just do:

let type = UTType(tag: "jpg", tagClass: .filenameExtension, conformingTo: nil)

and check whether the file name extension is e.g. that of an image by doing:

type?.isSubtype(of: .image)

Though bear in mind that the file does not necessarily represent an image just because its name says it is :)

Heisser answered 24/11, 2021 at 20:44 Comment(7)
@LanceSamaria I've updated with a list of UTTypes that does give you "jpg" and "png".Heisser
thanks it worked. About what you said in your answer. Why wouldn't it be an image the file extension says image? Would that also apply for .movie?Areca
For iOS 14 UTTypes, there are UTType.movie, UTType.video, UTType.audio, .rawVideo, .liveVideo. Does it apply for these meaning just because it says video and movie, doesn't mean that it's a video or movie?Areca
@LanceSamaria It's just a file name, after all. I can change it to whatever I want, regardless of the contents of the file. I can totally create a text file and call it cat.png. Basically, I'm saying the same thing as the warning in the documentation here. You should also use some other metric to determine the file type, if that is possible, otherwise you can't be 100% sure.Heisser
Ahhhhhh, you are are 100% correct, I overlooked that. THANK YOU for the advice :)!!! Do you have any SO links that I can use to check against that actual content itself?Areca
@LanceSamaria You can read the file. Many file types have signatures, and you can see how to check that here.Heisser
I’m looking at the links now. Thanks for your help! Happy Coding!Areca
F
8

For those who are looking for all possible types - here is the full list as of iOS 15:

func allUTITypes() -> [UTType] {
        let types : [UTType] =
            [.item,
             .content,
             .compositeContent,
             .diskImage,
             .data,
             .directory,
             .resolvable,
             .symbolicLink,
             .executable,
             .mountPoint,
             .aliasFile,
             .urlBookmarkData,
             .url,
             .fileURL,
             .text,
             .plainText,
             .utf8PlainText,
             .utf16ExternalPlainText,
             .utf16PlainText,
             .delimitedText,
             .commaSeparatedText,
             .tabSeparatedText,
             .utf8TabSeparatedText,
             .rtf,
             .html,
             .xml,
             .yaml,
             .sourceCode,
             .assemblyLanguageSource,
             .cSource,
             .objectiveCSource,
             .swiftSource,
             .cPlusPlusSource,
             .objectiveCPlusPlusSource,
             .cHeader,
             .cPlusPlusHeader]

        let types_1: [UTType] =
            [.script,
             .appleScript,
             .osaScript,
             .osaScriptBundle,
             .javaScript,
             .shellScript,
             .perlScript,
             .pythonScript,
             .rubyScript,
             .phpScript,
             .makefile, //'makefile' is only available in iOS 15.0 or newer
             .json,
             .propertyList,
             .xmlPropertyList,
             .binaryPropertyList,
             .pdf,
             .rtfd,
             .flatRTFD,
             .webArchive,
             .image,
             .jpeg,
             .tiff,
             .gif,
             .png,
             .icns,
             .bmp,
             .ico,
             .rawImage,
             .svg,
             .livePhoto,
             .heif,
             .heic,
             .webP,
             .threeDContent,
             .usd,
             .usdz,
             .realityFile,
             .sceneKitScene,
             .arReferenceObject,
             .audiovisualContent]

        let types_2: [UTType] =
            [.movie,
             .video,
             .audio,
             .quickTimeMovie,
             UTType("com.apple.quicktime-image"),
             .mpeg,
             .mpeg2Video,
             .mpeg2TransportStream,
             .mp3,
             .mpeg4Movie,
             .mpeg4Audio,
             .appleProtectedMPEG4Audio,
             .appleProtectedMPEG4Video,
             .avi,
             .aiff,
             .wav,
             .midi,
             .playlist,
             .m3uPlaylist,
             .folder,
             .volume,
             .package,
             .bundle,
             .pluginBundle,
             .spotlightImporter,
             .quickLookGenerator,
             .xpcService,
             .framework,
             .application,
             .applicationBundle,
             .applicationExtension,
             .unixExecutable,
             .exe,
             .systemPreferencesPane,
             .archive,
             .gzip,
             .bz2,
             .zip,
             .appleArchive,
             .spreadsheet,
             .presentation,
             .database,
             .message,
             .contact,
             .vCard,
             .toDoItem,
             .calendarEvent,
             .emailMessage,
             .internetLocation,
             .internetShortcut,
             .font,
             .bookmark,
             .pkcs12,
             .x509Certificate,
             .epub,
             .log]
                .compactMap({ $0 })

        return types + types_1 + types_2
    }

Note: I've intentionally split data into 3 arrays to speed up compilation time.

Farinose answered 8/5, 2022 at 22:8 Comment(0)
S
0

You should not try to compare the extension of the URL returned by UIDocumentPickerViewController to a known list of extensions. Instead, use url.resourceValues(forKeys: [.contentTypeKey]).contentType to get a UTType for the returned URL, and then check that it conforms to .image: type.conforms(to: .image).

Swenson answered 25/11, 2021 at 16:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.