IOS UTI(统一类型标识符) 根据文件后缀打开APP
前言
最近項(xiàng)目中有個(gè)需求,在iOS設(shè)備上使用iOS系統(tǒng)提供的內(nèi)容分享功能,從第三方App應(yīng)用直接分享實(shí)體內(nèi)容到我們的應(yīng)用中。其大概的原理是這樣的,首先為我們的iOS應(yīng)用注冊可以打開document types(文檔類型),然后在第三方應(yīng)用中,如果它們使用了iOS提供的分享功能,那么就會看到我們的應(yīng)用程序,點(diǎn)擊進(jìn)行分享。而關(guān)于需求的設(shè)計(jì)和實(shí)現(xiàn)的具體思路,我會在下一篇博客中詳細(xì)講解。這篇文章是來講一下蘋果在iOS和OS X系統(tǒng)中為了更好的進(jìn)行類型識別,而提供的一套統(tǒng)一的規(guī)范,也就是標(biāo)題中提到的“Uniform Type Identifier(UTI)”,我把它翻譯成“統(tǒng)一類型標(biāo)識符”,下面統(tǒng)一簡稱為“UTI”。
官方教程
網(wǎng)上關(guān)于UTI的使用教程少之又少,所以我只是參考了蘋果官方文檔提供的講解,這篇博客權(quán)當(dāng)是我對于官方文檔的一個(gè)理解吧!!自認(rèn)為很重要的部分,我會貼出來官方文檔原文,以便于大家學(xué)習(xí)理解,不至于被我的歪詞所誤導(dǎo),同時(shí)也推薦大家從開發(fā)者中心上搜一些文檔來看,這里推薦幾篇:
1.Cocoa Core Competencies – Uniform Type Identifier?
這篇文檔提供了一個(gè)視圖來說明UTI是什么,怎么工作和被誰使用,是個(gè)非常好的新手指南。
2.Uniform Type Identifier介紹和使用?
這篇文檔詳細(xì)得描述了UTI的基礎(chǔ)概念和屬性,還有它們的使用方法,內(nèi)容非常豐富,本文主要參考的就是這篇
3.System-Declared Uniform Type Identifiers?
這篇文檔提供了在OS X系統(tǒng)中定義的一個(gè)UTI的列表,我們可以查看每一種官方提供的UTI的定義和涵義。
4.UTType Reference?
這篇文檔提供了對UTI字符串直接操作的函數(shù)方法
5.一步一步為iOS應(yīng)用添加自定義的document type和新的UTI?
顧名思義,這篇文檔,講解的是如何在iOS應(yīng)用中導(dǎo)入新的UTI和添加自定義的document type。
為什么會有UTI
為什么會有UTI,打個(gè)比方,它就像是如今世界各國作為官方語言統(tǒng)講得英文。為什么這么比喻呢,因?yàn)橹袊酥v母語漢語,法國人講母語法語,但是如果一個(gè)中國人到了法國,而又不懂法語,碰到的法國人不懂漢語,那么他們?nèi)绾谓涣鳒贤?#xff0c;這就是英文的用武之地了。而相對而言,蘋果操作系統(tǒng)相當(dāng)于整個(gè)世界,各個(gè)不同的程序或者服務(wù)相當(dāng)于各個(gè)國家,倆個(gè)不同的程序想要互通交流,就比如互相發(fā)送文件,可是一個(gè)使用文件擴(kuò)展名,一個(gè)使用MIME類型,倆者的數(shù)據(jù)類型不同,無法解析,都互相不認(rèn)識,那么怎么交流溝通呢?在這樣的情景下,UTI就有了用武之地啦,它就充當(dāng)?shù)氖乾F(xiàn)實(shí)世界的英文這個(gè)角色。
UTI概念
Uniform type identifiers(UTIs)提供了在整個(gè)系統(tǒng)里面標(biāo)識數(shù)據(jù)的一個(gè)統(tǒng)一的方式,比如documents(文檔)、pasteboard data(剪貼板數(shù)據(jù))和bundles(包)。而具體到UTI的定義,官方文檔是這么說的,“A uniform type identifier is a string that uniquely identifies a class of entities considered to have a ‘type’.”。其大概意思是說,一個(gè)統(tǒng)一類型標(biāo)識符是一個(gè)唯一標(biāo)識一種擁有"類型"屬性實(shí)體的字符串。而且,針對這個(gè)“type”,官方文檔還給我們提出了例子解釋,對于一個(gè)文件或者是字節(jié)流來說,“type”指的的數(shù)據(jù)類型;而對于packages和bundles來說,“type”指的就是它們內(nèi)部的目錄層級結(jié)構(gòu)。
UTI用途
大多數(shù)情況下,一個(gè)UTI提供的是系統(tǒng)中所有程序和服務(wù)都能夠識別并且依賴的一個(gè)唯一的標(biāo)識,這么講可能有些太抽象,我們使用一下官方文檔中給出的例子,比如一個(gè)JPEG類型的圖片文件,在不同的環(huán)境下,可以有下面幾種不同的標(biāo)識方法:
1.‘JPEG’, OSType表示,
2.‘.jpg’, 文件擴(kuò)展名
3.jpeg’, 文件擴(kuò)展名
4.‘image/jpeg’, MIME(多用途互聯(lián)網(wǎng)郵件擴(kuò)展類型)中的一種類型
而UTI則是用‘public.jpeg’這個(gè)字符串標(biāo)識,完全代替了這些不一致的標(biāo)簽,這個(gè)字符串和其他任何一個(gè)舊標(biāo)簽都是完全兼容的,而且他們之間可以相互轉(zhuǎn)換。由于UTI可以標(biāo)識任何類型的實(shí)體,所以他們相對于舊標(biāo)簽來說靈活性更強(qiáng)了;使用UTI我們可以表示下面這些實(shí)體:
Pasteboard data
Folders (directories)
Bundles
Frameworks
Streaming data
Aliases and symbolic links
用法
1.簡介
Apple給我們提供了在iOS和Mac應(yīng)用中通用的UTI字符串集合,比如,‘public.data’、‘public.item’、‘public.image’等,這些我們都可以在官方文檔中進(jìn)行查閱他們的涵義。除此之外,我們也可以在應(yīng)用程序中自定義自己的UTI字符串,比如我們可以定義一個(gè)標(biāo)識特殊文檔格式的UTI字符串叫’cc.icoc.shaobozheng’,如果其他的應(yīng)用程序想要支持我們這種格式的文檔,他們就可以用’cc.icoc.shaobozheng’來標(biāo)識我們的文檔。
2.字符集
看到我們上邊的舉例了,那么我們來說一下定義UTI字符串時(shí)所用到的字符集。通常一個(gè)UTI字符串是一個(gè)包含ASCII字符的Unicode字符串,同時(shí)也可以加入羅馬字母和阿拉伯?dāng)?shù)字,如(A-Z),(a-z),(0-9)還有點(diǎn)號(“.”)和連接符(“-”)。而任何包含非法字符的字符串,如包含下劃線’_',都無法作為UTI來標(biāo)識內(nèi)容,而且Apple不會有任何錯(cuò)誤反饋。
3.語法
就像我上面的例子一樣,UTI的定義和我們開發(fā)iOS程序時(shí)填寫organization時(shí)一樣,采取的是反域名規(guī)則。如下面這幾種:
com.apple.quicktime-movie
com.mycompany.myapp.myspecialfiletype
public.html
com.apple.pict
public.jpeg
而UTI中的域名,如‘com’、‘public’這些,僅僅是用來表示這個(gè)UTI字符串在域名層級中的位置,它不會影響任何相似類型的分組。比如,‘public’域名就是大部分應(yīng)用程序用來標(biāo)識標(biāo)準(zhǔn)類型的,而目前僅僅只有Apple可以創(chuàng)建‘public’域名的UTI。
另外,我們可能會碰到的是一種‘dyn’域名,是動態(tài)域名,意思就是我們使用中,不會指定這種類型的UTI為某一個(gè)字符串,然后系統(tǒng)運(yùn)行過程中,會自動識別幫我們處理。針對這種動態(tài)標(biāo)識,我們是看不到的,但是我們可以通過UTI字符串的操作方式轉(zhuǎn)換成我們的常用類型,比如OSType,MIME類型等。官方文檔中,對動態(tài)標(biāo)識有個(gè)比喻,“You can think of a dynamic identifier as a UTI-compatible wrapper around an otherwise unknown filename extension, MIME type, OSType, and so on”,大概意思就是我們可以把這種動態(tài)標(biāo)識當(dāng)做是針對普通類型進(jìn)行了重寫包裝的,而且是兼容UTI的一種標(biāo)識。
最后一種就是可以自定義的域名,代表性的就是‘com’域名,Apple也給我們提供了一些他們定義的’com’域名的UTI。
順應(yīng)性
UTI相對于其他那些舊標(biāo)簽的一個(gè)關(guān)鍵優(yōu)勢就是在于,它可以在一個(gè)順應(yīng)結(jié)構(gòu)中聲明。而用我們面向?qū)ο蟮姆绞秸f,UTI就是可繼承的,而且是多繼承方式。先上圖:
如上圖所示,‘public.html’這個(gè)UTI就是繼承于‘public.text’這個(gè)UTI,因?yàn)椤畃ublic.html’標(biāo)識的是HTML文本格式,也屬于是文本格式的一種,而文本、圖片等等這些內(nèi)容又都屬于是數(shù)據(jù)的一種,所以他們繼承于’public.data’這個(gè)UTI。
上面這個(gè)圖示指的是UTI中的內(nèi)容形式的繼承結(jié)構(gòu),此外,原則上來說,指定UTI層次的時(shí)候,即可以指定它的功能結(jié)構(gòu),也可以指定它的物理結(jié)構(gòu),上圖是就是一個(gè)內(nèi)容結(jié)構(gòu)圖.物理結(jié)構(gòu)指的就是這個(gè)UTI的物理實(shí)質(zhì),比如它標(biāo)識一個(gè)目錄,一個(gè)文件等,而功能結(jié)構(gòu)指的就是這個(gè)UTI的用圖,比如同樣是文件,它標(biāo)識的可以是圖片、視頻等等。 而一般指定UTI層次結(jié)構(gòu)的規(guī)則是:
1.一個(gè)UTI在物理層次上需要繼承‘public.item’
2.一個(gè)UTI在功能層次需要繼承非’public.item’之外的UTI。
然而,指定UTI的功能層次并不是強(qiáng)制的,但是這樣做是考慮到可以更好地將UTI集成到系統(tǒng)一些特性中,就比如Spotlight應(yīng)用,就可以把我們指定的功能性UTI和命名屬性聯(lián)系起來。下面是一個(gè)UTI功能順應(yīng)結(jié)構(gòu)和物理順應(yīng)結(jié)構(gòu)圖:
這個(gè)順序性使得我們的UTI在決定類型上擁有更高的靈活性,不僅避免了大量的條件判斷的使用,而且還可以關(guān)聯(lián)你想不到的一些類型。
使用UTI
應(yīng)用場景
在Mac OS中我們開發(fā)應(yīng)用時(shí)我們可以經(jīng)常使用到UTI,但是在開發(fā)iOS應(yīng)用程序時(shí),我們應(yīng)用到UTI的場景不是很多,這也是現(xiàn)在網(wǎng)上教程偏少得原因。而在iOS開發(fā)中,一般我們使用UTI來標(biāo)識剪貼板的類型。而在具體使用到Apple給我們提供的UTI字符串的時(shí)候,我們必須使用在UTCoreTypes.h文件中定義的常量來代替直接使用字符串。關(guān)于UIPasteboard的詳細(xì)使用,大家可以去這篇博客中詳細(xì)學(xué)習(xí)一下:精通UIPasteboard粘貼板。
操作方法
現(xiàn)在我們來看一下蘋果提供的一些直接操作UTI的函數(shù)方法,簡單列舉幾個(gè)。我們可以在MobileCoreServices這個(gè)framework中的UIType.h文件中找到,我們也可以仔細(xì)的看一下這個(gè)framework中的其他文件,都是對UTI的一些定義和生命。
1.UITypeEqual
判斷倆個(gè)UTI是否完全一樣,后者是一個(gè)動態(tài)標(biāo)簽說明是否是另外一個(gè)UTI標(biāo)簽說明的子集。
2.UITypeConformsTo
判斷倆個(gè)標(biāo)簽的順應(yīng)性,用面向?qū)ο蟮慕嵌壤斫?#xff0c;就是判斷是否是子類。
3.UTTypeCreatePreferredIdentifierForTag
通過其他類型標(biāo)識符,如MIME標(biāo)識符,轉(zhuǎn)換成UTI,當(dāng)可以創(chuàng)建多個(gè)UTI字符串時(shí),一般返回’public’域名的UTI。
4.UTTypeCreateAllIdentifiersForTag
通過其他類型標(biāo)識符,如MIME標(biāo)識符,轉(zhuǎn)換成UTI,當(dāng)可以創(chuàng)建多個(gè)UTI字符串時(shí),返回所有的UTIs,讓你自己選
5.UTTypeCopyPreferredTagWithClass
交換UTI字符串標(biāo)識
自定義UTI
用法
蘋果允許Mac開發(fā)者為他們的Mac App中獨(dú)有的數(shù)據(jù)格式自定義新的UTI。它們一般被聲明在下面幾個(gè)文件中
Info.plist
Application bundles
Spotlight Importer bundles
Automator action bundles
使用官方給我們的一個(gè)UTI聲明的例子,Public.jpeg聲明:
UTExportedTypeDeclarations
UTTypeIdentifier
public.jpeg
UTTypeReferenceURL
http://www.w3.org/Graphics/JPEG/;
UTTypeDescription
JPEG image
UTTypeIconFile
public.jpeg.icns
UTTypeConformsTo
public.image
public.data
UTTypeTagSpecification
com.apple.ostype
JPEG
public.filename-extension
jpeg
jpg
public.mime-type
image/jpeg
一個(gè)UTI聲明的屬性列表:
Value type
Description
UTExportedTypeDeclarations
array of dictionaries
An array of exported UTI declarations (that is, identifiers owned by the bundle’s publisher).
UTImportedTypeDeclarations
array of dictionaries
An array of imported UTI declarations (that is, identifiers owned by another company or organization).
UTTypeIdentifier
string
The UTI for the declared type. This key is required for UTI declarations.
UTTypeTagSpecification
dictionary
A dictionary defining one or more equivalent type identifiers.
UTTypeConformsTo
array of strings
The UTIs to which this identifier conforms.
UTTypeIconFile
string
The name of the bundle icon resource to associate with this UTI.
UTTypeDescription
string
A user-visible description of this type. You can localize this string by including it in an InfoPlist.strings file.
UTTypeReferenceURL
string
The URL of a reference document describing this type.
而且自定義的UTI必須指定UTExportedTypeDeclarations或者UTImportedTypeDeclarations,這樣第三方App都可以使用,要么被導(dǎo)入到項(xiàng)目中的其他沒有擁有這種數(shù)據(jù)格式的bundle中,這樣都可以看得到。而官方文檔中有一句話,“If both imported and exported declarations for a UTI exist, the exported declaration takes precedence over imported one”,我的理解是,被導(dǎo)出去得UTI聲明所有人是定義UTI的發(fā)布者,而被導(dǎo)入的UTI聲明所有人就是其他人,所以就是說如果對于一個(gè)UTI來說,倆種類型的聲明都存在,則被導(dǎo)出的UTI聲明優(yōu)先使用。
自定義UTI的建議
1.你的UTI字符串必須是唯一的。以‘com.’開頭的反域名命名方式是確保唯一性的簡單有效的方法。
2.如果你的代碼依賴于第三方App,UTI類型或許不會在系統(tǒng)中展示,你應(yīng)該在bundle中聲明為導(dǎo)入類型
3.如果你的UTI類型是一個(gè)或多個(gè)已存在的UTI類型的子類,則必須給它添加順應(yīng)性,讓它繼承于某個(gè)父類。最好是繼承于‘public’類型。
總結(jié)
以上是生活随笔為你收集整理的IOS UTI(统一类型标识符) 根据文件后缀打开APP的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 谈谈对CNN在NLP中可行性的理解
- 下一篇: 研修国学请注意选好教材