27

I'm learning swift , and I made a table with cells that show an image ,and classes in groups by MIME TYPE (using path extension). I had a question about extensions. If the images (for example, it could be a video or a pdf) are taken from internet , i'm not sure if they have the extension or not how can I get the MIMEtype of a file inside my file System without using path extension ? PS :Sorry for my bad english it's not my native language

kholl
  • 609
  • 1
  • 6
  • 20

10 Answers10

80

If anyone wants to get the MimeType from the actual URL of the file this code worked for me:

import MobileCoreServices

func mimeTypeForPath(path: String) -> String {
    let url = NSURL(fileURLWithPath: path)
    let pathExtension = url.pathExtension

    if let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension! as NSString, nil)?.takeRetainedValue() {
        if let mimetype = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue() {
            return mimetype as String
        }
    }
    return "application/octet-stream"
}
Ismail
  • 2,778
  • 2
  • 24
  • 39
Paul Lehn
  • 3,202
  • 1
  • 24
  • 29
19

iOS 14.0 +

Use the extensions

import UniformTypeIdentifiers

extension NSURL {
    public func mimeType() -> String {
        if let pathExt = self.pathExtension,
            let mimeType = UTType(filenameExtension: pathExt)?.preferredMIMEType {
            return mimeType
        }
        else {
            return "application/octet-stream"
        }
    }
}

extension URL {
    public func mimeType() -> String {
        if let mimeType = UTType(filenameExtension: self.pathExtension)?.preferredMIMEType {
            return mimeType
        }
        else {
            return "application/octet-stream"
        }
    }
}

extension NSString {
    public func mimeType() -> String {
        if let mimeType = UTType(filenameExtension: self.pathExtension)?.preferredMIMEType {
            return mimeType
        }
        else {
            return "application/octet-stream"
        }
    }
}

extension String {
    public func mimeType() -> String {
        return (self as NSString).mimeType()
    }
}

Below iOS 14

MimeType.swift

import Foundation

internal let DEFAULT_MIME_TYPE = "application/octet-stream"

internal let mimeTypes = [
    "html": "text/html",
    "htm": "text/html",
    "shtml": "text/html",
    "css": "text/css",
    "xml": "text/xml",
    "gif": "image/gif",
    "jpeg": "image/jpeg",
    "jpg": "image/jpeg",
    "js": "application/javascript",
    "atom": "application/atom+xml",
    "rss": "application/rss+xml",
    "mml": "text/mathml",
    "txt": "text/plain",
    "jad": "text/vnd.sun.j2me.app-descriptor",
    "wml": "text/vnd.wap.wml",
    "htc": "text/x-component",
    "png": "image/png",
    "tif": "image/tiff",
    "tiff": "image/tiff",
    "wbmp": "image/vnd.wap.wbmp",
    "ico": "image/x-icon",
    "jng": "image/x-jng",
    "bmp": "image/x-ms-bmp",
    "svg": "image/svg+xml",
    "svgz": "image/svg+xml",
    "webp": "image/webp",
    "woff": "application/font-woff",
    "jar": "application/java-archive",
    "war": "application/java-archive",
    "ear": "application/java-archive",
    "json": "application/json",
    "hqx": "application/mac-binhex40",
    "doc": "application/msword",
    "pdf": "application/pdf",
    "ps": "application/postscript",
    "eps": "application/postscript",
    "ai": "application/postscript",
    "rtf": "application/rtf",
    "m3u8": "application/vnd.apple.mpegurl",
    "xls": "application/vnd.ms-excel",
    "eot": "application/vnd.ms-fontobject",
    "ppt": "application/vnd.ms-powerpoint",
    "wmlc": "application/vnd.wap.wmlc",
    "kml": "application/vnd.google-earth.kml+xml",
    "kmz": "application/vnd.google-earth.kmz",
    "7z": "application/x-7z-compressed",
    "cco": "application/x-cocoa",
    "jardiff": "application/x-java-archive-diff",
    "jnlp": "application/x-java-jnlp-file",
    "run": "application/x-makeself",
    "pl": "application/x-perl",
    "pm": "application/x-perl",
    "prc": "application/x-pilot",
    "pdb": "application/x-pilot",
    "rar": "application/x-rar-compressed",
    "rpm": "application/x-redhat-package-manager",
    "sea": "application/x-sea",
    "swf": "application/x-shockwave-flash",
    "sit": "application/x-stuffit",
    "tcl": "application/x-tcl",
    "tk": "application/x-tcl",
    "der": "application/x-x509-ca-cert",
    "pem": "application/x-x509-ca-cert",
    "crt": "application/x-x509-ca-cert",
    "xpi": "application/x-xpinstall",
    "xhtml": "application/xhtml+xml",
    "xspf": "application/xspf+xml",
    "zip": "application/zip",
    "epub": "application/epub+zip",
    "docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
    "xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    "pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
    "mid": "audio/midi",
    "midi": "audio/midi",
    "kar": "audio/midi",
    "mp3": "audio/mpeg",
    "ogg": "audio/ogg",
    "m4a": "audio/x-m4a",
    "ra": "audio/x-realaudio",
    "3gpp": "video/3gpp",
    "3gp": "video/3gpp",
    "ts": "video/mp2t",
    "mp4": "video/mp4",
    "mpeg": "video/mpeg",
    "mpg": "video/mpeg",
    "mov": "video/quicktime",
    "webm": "video/webm",
    "flv": "video/x-flv",
    "m4v": "video/x-m4v",
    "mng": "video/x-mng",
    "asx": "video/x-ms-asf",
    "asf": "video/x-ms-asf",
    "wmv": "video/x-ms-wmv",
    "avi": "video/x-msvideo"
]

internal func MimeType(ext: String?) -> String {
    return mimeTypes[ext?.lowercased() ?? "" ] ?? DEFAULT_MIME_TYPE
}

extension NSURL {
    public func mimeType() -> String {
        return MimeType(ext: self.pathExtension)
    }
}

extension URL {
    public func mimeType() -> String {
        return MimeType(ext: self.pathExtension)
    }
}

extension NSString {
    public func mimeType() -> String {
        return MimeType(ext: self.pathExtension)
    }
}

extension String {
    public func mimeType() -> String {
        return (self as NSString).mimeType()
    }
}

How to use

let string = "https://homepages.cae.wisc.edu/~ece533/images/boat.png"

let mimeType = string.mimeType()

Workes with NSURL, URL, NSString, String

Reference 1

Reference 2

Sreekuttan
  • 1,579
  • 13
  • 19
10

If you need to check URL contains some Image or Audio file or Video file, here is Swift 5.1 code:

import Foundation
import MobileCoreServices

extension URL {
    func mimeType() -> String {
        let pathExtension = self.pathExtension
        if let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension as NSString, nil)?.takeRetainedValue() {
            if let mimetype = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue() {
                return mimetype as String
            }
        }
        return "application/octet-stream"
    }
    var containsImage: Bool {
        let mimeType = self.mimeType()
        guard let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeType as CFString, nil)?.takeRetainedValue() else {
            return false
        }
        return UTTypeConformsTo(uti, kUTTypeImage)
    }
    var containsAudio: Bool {
        let mimeType = self.mimeType()
        guard let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeType as CFString, nil)?.takeRetainedValue() else {
            return false
        }
        return UTTypeConformsTo(uti, kUTTypeAudio)
    }
    var containsVideo: Bool {
        let mimeType = self.mimeType()
        guard  let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeType as CFString, nil)?.takeRetainedValue() else {
            return false
        }
        return UTTypeConformsTo(uti, kUTTypeMovie)
    }

}
Dmih
  • 530
  • 6
  • 9
6

To fetch an extension from UTI, here is Swift 4.1 code:

import AVFoundation

extension AVFileType {
    /// Fetch and extension for a file from UTI string
    var fileExtension: String {
        if let ext = UTTypeCopyPreferredTagWithClass(self as CFString, kUTTagClassFilenameExtension)?.takeRetainedValue() {
            return ext as String
        }
        return "None"
    }
}

mov for com.apple.quicktime-movie

Nike Kov
  • 12,630
  • 8
  • 75
  • 122
5

Swift 5.5 iOS 14.0+

import UniformTypeIdentifiers

extension URL {
    
    var mimeType: String {
        return UTType(filenameExtension: self.pathExtension)?.preferredMIMEType ?? "application/octet-stream"
    }
    
    func contains(_ uttype: UTType) -> Bool {
        return UTType(mimeType: self.mimeType)?.conforms(to: uttype) ?? false
    }

}

//Example:
let fileUrl = URL(string: "../myFile.png")!
print(fileUrl.contains(.image))
print(fileUrl.contains(.video))
print(fileUrl.contains(.text))
Hassan Taleb
  • 2,350
  • 2
  • 19
  • 24
2

iOS15 compatible version of @Dmih's solution looks like this:

import UniformTypeIdentifiers

extension URL {
    func mimeType() -> String {
        let pathExtension = self.pathExtension
        if let type = UTType(filenameExtension: pathExtension) {
            if let mimetype = type.preferredMIMEType {
                return mimetype as String
            }
        }
        return "application/octet-stream"
    }
    
    var containsImage: Bool {
        let mimeType = self.mimeType()
        if let type = UTType(mimeType: mimeType) {
            return type.conforms(to: .image)
        }
        return false
    }
    
    var containsAudio: Bool {
        let mimeType = self.mimeType()
        if let type = UTType(mimeType: mimeType) {
            return type.conforms(to: .audio)
        }
        return false
    }
    
    var containsMovie: Bool {
        let mimeType = self.mimeType()
        if let type = UTType(mimeType: mimeType) {
            return type.conforms(to: .movie)   // ex. .mp4-movies
        }
        return false
    }
    
    var containsVideo: Bool {
        let mimeType = self.mimeType()
        if let type = UTType(mimeType: mimeType) {
            return type.conforms(to: .video)
        }
        return false
    }
}
iKK
  • 6,394
  • 10
  • 58
  • 131
1

Assuming you are receiving your data as NSData, follow this Post: https://stackoverflow.com/a/5042365/2798777

In Swift for example:

var c = [UInt32](count: 1, repeatedValue: 0)
(data as! NSData).getBytes(&c, length: 1)
switch (c[0]) {
case 0xFF, 0x89, 0x00:
    println("image")
case 0x47:
    println("gif")
default: 
    println("unknown: \(c[0])")
}
Community
  • 1
  • 1
matthias
  • 947
  • 1
  • 9
  • 27
0

With the help of answer given by @Dmih , I have modified it according to my project requirement which needs mime type string to upload the selected file. Which may help to someone else.

  import Foundation
  import MobileCoreServices



  extension URL {
                func mimeType() -> String {
                    let pathExtension = self.pathExtension
                    if let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension as NSString, nil)?.takeRetainedValue() {
                        if let mimetype = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue() {
                            return mimetype as String
                        }
                    }
                    return "application/octet-stream"
                }
                var containsImage: Bool {
                    let mimeType = self.mimeType()
                    guard let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeType as CFString, nil)?.takeRetainedValue() else {
                        return false
                    }
                    return UTTypeConformsTo(uti, kUTTypeImage)
                }
                var containsAudio: Bool {
                    let mimeType = self.mimeType()
                    guard let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeType as CFString, nil)?.takeRetainedValue() else {
                        return false
                    }
                    return UTTypeConformsTo(uti, kUTTypeAudio)
                }
                var containsVideo: Bool {
                    let mimeType = self.mimeType()
                    guard  let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeType as CFString, nil)?.takeRetainedValue() else {
                        return false
                    }
                    return UTTypeConformsTo(uti, kUTTypeMovie)
                }

            //Get current mime type of url w.r.t its url
                var currentMimeType: String {

                    if self.containsImage{
                        return "image/png"
                    }else if self.containsAudio{
                        return "audio/mp3"
                    }else if self.containsVideo{
                        return "video/mp4"
                    }

                    return ""
                }
            }
Prasanna
  • 945
  • 10
  • 24
0

iOS 15

import AVFoundation

public extension AVFileType {
    /// Fetch and extension for a file from UTI string
    var fileExtension: String {
        guard let type = UTType(self.rawValue),
              let preferredFilenameExtension = type.preferredFilenameExtension
        else {
            return "None"
        }
        return preferredFilenameExtension
    }
}
moyoteg
  • 351
  • 3
  • 11
0

Answer that provided by Paul Lehn(most liked answer) didn't work for me, because I'm developing for iOS 16 at this moment, due to deprecation of methods that was used in his solution, I decided to refactor the code a bit:

iOS 14+

import AVFoundation

// url to the file in the file system
func mimeTypeForURL(_ url: URL) -> String? {
    let pathExtension = url.pathExtension
    
    guard let uti = UTType(filenameExtension: pathExtension),
       let mimeType = uti.preferredMIMEType else {
        return nil
    }
    
    return mimeType
}
Suprafen
  • 58
  • 3
  • 9