小问题

iOS 统一类型标识符:通过后缀判断文件类型

2017-05-03  本文已影响1703人  anyoptional
首先了解UTI和MIME的概念

1.同一类型标识符(Uniform Type Identifier,UTI)代表IOS信息共享的中心组件。可以把它看成下一代的MIME类型。UTI是标识资源类型(比如图像和文本)的字符串,他们制定哪些类型的信息将用于公共数据对象,他们不需要依赖于老式的指示符,比如文件扩展名,MIME类型,或者文件类型的元数据


Paste_Image.png

如图,显示了Apple的基本顺应树的一部分。这个树上位于较低位置的任何项目都必须顺应其所有父数据属性。声明一个父UTI意味着支持他的所有子UTI。因此,可以打开public.data的应用必须能打开文本,电影,图像文件等。其UTI的名称类型就是public.data等

2.MIME(Multipurpose Internet Mail Extensions)多用于互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
在HTTP请求中对应HTTP header的Content-type关键字。MIME类型与文档后缀有关。

常见的文件扩展名之间的相互转换

首先在头文件中添加导入 <MobileCoreServices/MobileCoreServices.h>
(1)后缀名字符串转化为UTI字符串

 -(NSString *)preferredUTIForExtention:(NSString *)ext
{
    //Request the UTI via the file extension
    NSString *theUTI = (__bridge_transfer NSString     *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)(fileExtension), NULL);
    return theUTI;
}

(2)使用kUTTagClassMIMEType作为第一个参数,给UTTypeCreatePreferredIdentifierForTag(),是MIME类型字符串转化为UTI字符串

NSString *preferredUTIForMIMEType(NSString *mime)
{
    //request the UTI via the file extention
    NSString *theUTI = (__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType,(__bridge CFStringRef)mimeType, NULL);
    return theUTI;
}

(3)使用UTTypeCopyPreferredTagWithClass(),是UTI字符串转化为后缀扩展名

NSString *extensionForUTI(NSString *aUTI)
{
    CFStringRef theUTI = (__bridge CFStringRef)aUTI;
    CFStringRef results = UTTypeCopyPreferredTagWithClass(theUTI, kUTTagClassFilenameExtension);
    return (__bridge_transfer NSString *)results;
}

(4)UTI字符串转化为MIME类型

NSString *mimeTypeForUTI(NSString *aUTI)
{
    CFStringRef theUTI = (__bridge CFStringRef) aUTI;
    CFStringRef results = UTTypeCopyPreferredTagWithClass(theUTI, kUTTagClassMIMEType);
    return (__bridge_transfer NSString *)results;
}

(5)测试顺应性,使用UTTypeConformsTo()函数测试顺应性。该函数接受两个参数:一个源UTI和一个要比较的UTI,如果第一个UTI顺应第二个UTI,就返回True。相等性测试则使用UITypeEqual(),下面显示了一个示例,说明如何顺应性测试,确定文件路径是否可能指向图像资源。

BOOL pathPointsToLikelyUTIMatch(NSString *path, CFStringRef theUTI)
{
    NSString *extension = path.pathExtension;
    NSString *preferredUTI = preferredUTIForExtension(extension);
    return (UTTypeConformsTo((__bridge CFStringRef) preferredUTI, theUTI));
}

BOOL pathPointsToLikelyImage(NSString *path)
{
     return pathPointsToLikelyUTIMatch(path, CFSTR("public.image"));
}

BOOL pathPointsToLikelyAudio(NSString *path)
{
    return pathPointsToLikelyUTIMatch(path, CFSTR("public.audio"));
}

(6)获取顺应性列表

UTTypeCopyDeclaration()是IOS API中的所有UTI函数中最一般(并且最有用)的函数,它返回包含以下键的字典。

》kUTTypeIdentifierKey:UTI名称,他将被传递给函数(例如.public.mpeg)

》kUTTypeConformsToKey:类型顺应的任何父项目(例如 public.mpeg顺应public.movie)

》kUTTypeDescriptionKey:正在考虑的类型(如果存在的话)的现实描述 (例如 “MPEG movie”)

》kUTTypeTagSpecificationKey:给定UTI的等价OSType(例如MPG和MPEG)、文件扩展名( mpg、mpeg、mpe、m75和m15)和MIME类型(视频/mpeg、视频/mpg、视频/x-mpeg和视频/x-mpg)的字典。

下面例子主要是返回字典向上通过顺应性树来构建一个数组,表示给定UTI顺序的所有项目.例如public.mpeg类型顺应public.movie public.audiovisual-content public.data public.item 和public.content,代码如下:

NSDictionary *utiDictionary(NSString *aUTI)
{
    NSDictionary *dictionary = (__bridge_transfer NSDictionary *)UTTypeCopyDeclaration((__bridge CFStringRef) aUTI);
    return dictionary;
}

NSArray *uniqueArray(NSArray *anArray)
{
    NSMutableArray *copiedArray = [NSMutableArray arrayWithArray:anArray];
    for (id object in anArray)
    {
        [copiedArray removeObjectIdenticalTo:object];
        [copiedArray addObject:object];
    }

    return copiedArray;
}

NSArray *conformanceArray(NSString *aUTI)
{
    NSMutableArray *results = [NSMutableArray arrayWithObject:aUTI];
    NSDictionary *dictionary = utiDictionary(aUTI);
    id conforms = dictionary[(__bridge NSString *)kUTTypeConformsToKey];

// No conformance
    if (!conforms) return results;

// Single conformance
    if ([conforms isKindOfClass:[NSString class]])
    {
        [results addObjectsFromArray:conformanceArray(conforms)];
        return uniqueArray(results);
    }

// Iterate through multiple conformance
    if ([conforms isKindOfClass:[NSArray class]])
    {
        for (NSString *eachUTI in (NSArray *) conforms)
            [results addObjectsFromArray:conformanceArray(eachUTI)];
        return uniqueArray(results);
    }

// Just return the one-item array
    return results;
}

NSArray *allExtensions(NSString *aUTI)
{
    NSMutableArray *results = [NSMutableArray array];
    NSArray *conformance = conformanceArray(aUTI);
    for (NSString *eachUTI in conformance)
    {
        NSDictionary *dictionary = utiDictionary(eachUTI);
        NSDictionary *extensions = dictionary[(__bridge NSString *)kUTTypeTagSpecificationKey];
        id fileTypes = extensions[(__bridge NSString *)kUTTagClassFilenameExtension];
    
        if ([fileTypes isKindOfClass:[NSArray class]])
            [results addObjectsFromArray:(NSArray *) fileTypes];
        else if ([fileTypes isKindOfClass:[NSString class]])
            [results addObject:(NSString *) fileTypes];
    }

    return uniqueArray(results);
}

NSArray *allMIMETypes(NSString *aUTI)
{
    NSMutableArray *results = [NSMutableArray array];
    NSArray *conformance = conformanceArray(aUTI);
    for (NSString *eachUTI in conformance)
    {
        NSDictionary *dictionary = utiDictionary(eachUTI);
        NSDictionary *extensions = dictionary[(__bridge NSString *)kUTTypeTagSpecificationKey];
        id fileTypes = extensions[(__bridge NSString *)kUTTagClassMIMEType];
    
        if ([fileTypes isKindOfClass:[NSArray class]])
            [results addObjectsFromArray:(NSArray *) fileTypes];
        else if ([fileTypes isKindOfClass:[NSString class]])
            [results addObject:(NSString *) fileTypes];
    }
    return uniqueArray(results);
}
上一篇 下一篇

猜你喜欢

热点阅读