本節書摘來自異步社群《ios 6進階開發手冊(第4版)》一書中的第2章,第2.1節秘訣:處理統一類型辨別符,作者 【美】erica sadun,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視
2.1 秘訣:處理統一類型辨別符
ios 6進階開發手冊(第4版)
統一類型辨別符(uniform type identifier,uti)代表ios資訊共享的中心元件。可以把它們視作下一代mime類型。uti是辨別資源類型(比如圖像和文本)的字元串,它們指定哪些類型的資訊将用于公共資料對象。它們不需要為此依賴于老式的訓示符,比如檔案擴充名、mime類型,或者檔案類型的中繼資料(比如ostype)。uti利用更新、更靈活的技術替代了這些項目。
uti使用反向域名風格的命名約定。常見的源于apple的辨別符看起來如下:public.html和public.jpeg,它們分别指html源文本和jpeg圖像,二者都是專用的檔案資訊類型。
繼承對于uti起着重要作用。uti使用類似于oo的繼承系統,其中子uti具有對父uti的“is-a”(是一個)關系。子uti會繼承它們的父uti的所有屬性,但是會添加它們表示的資料種類的更多特征。這是由于每個uti都可以根據需要承擔更一般或者更特定的角色。例如,以jpeg uti為例。jpeg圖像(public.jpeg)是一幅圖像(public.image),而圖像反過來又是一種資料(public.data),資料反過來又是一種使用者可檢視(或者可收聽)的内容(public.content),它是一種項目(public.item),即用于uti的普通的基本類型。這種層次結構被稱為順應性,其中子uti順應父uti。例如,更具體的jpeg uti順應更一般的圖像或資料uti。
圖2-1顯示了apple的基本順應性樹的一部分。這棵樹上位于較低位置的任何項目都必須順應其所有父資料屬性。聲明一個父uti意味着支援它的所有子uti。是以,可以打開public.data的應用程式必須能夠服務于文本、電影、圖像檔案等。

uti支援多重繼承。一個項目可以順應多個父uti 。是以,你可能設想一種同時提供文本和圖像容器的資料類型,它聲明了對二者的順應性。
沒有用于uti項目的中心系統資料庫,盡管每個uti都應該遵守約定。public域是為特定于ios的類型預留的,是大多數應用程式所共有的。apple生成了公共項目的一個完整的家族層次結構。可以使用标準的預留域命名方式添加任何特定于第三方公司的名稱(例如,com.sadun.mycustomtype和com.apple.quicktime-movie)。
2.1.1 通過檔案擴充名确定uti
mobile core services架構提供了一些實用程式,允許基于檔案擴充名擷取uti資訊。在使用這些基于c語言的函數時,一定要包括頭檔案,并把應用程式連接配接到架構。當給下面的函數傳遞一個路徑擴充字元串時,它将傳回一個首選的uti。首選的辨別符是單個uti字元串:
可以使用kuttagclassmimetype作為第一個參數,給uttypecreatepreferredidentifierfortag()傳遞一種mime類型代替檔案擴充名。該函數将為給定的mime類型傳回首選的uti:
結合使用這些函數,将允許你從檔案擴充名和mime類型轉向用于現代檔案通路uti類型。
2.1.2 從uti轉向擴充名或mime類型
也可以另辟蹊徑,從uti産生首選的擴充名或mime類型,這要使用uttypecopy preferredtagwithclass()。當給下面的函數傳遞public.jpeg時,它們将分别傳回jpeg和image/jpeg:
必須在葉子層使用這些函數,這意味着直接在該層級聲明類型擴充名。擴充名聲明在屬性清單中,其中将描述像檔案擴充名和預設圖示這樣的特性。是以,例如,給擴充名函數傳遞public.text或public.movie将傳回nil,而public.plain-text和public.mpeg則将分别傳回擴充名txt和mpg。
前面的項目将在順應性樹中處于較高的位置,進而提供一種抽象類型,而不是特定的實作。對于目前為應用程式定義的給定類,沒有現成的api函數用于尋找從它傳承下來的項目。你可能想在bugreport.apple.com上歸檔一個增強請求。誠然,所有的擴充名和mime類型都會注冊在某個位置(否則,uttypecopypreferredtagwithclass()将怎樣從一開始就執行向上查找的工作),是以把擴充名映射到更一般的uti的能力應該是可能存在的。
mime助手
盡管從擴充名到uti的服務是很詳盡的,可以為幾乎任何擴充名傳回uti,但是從uti到mime的結果則很随意,有些漫無目标。通常可以為任何公共項目生成正确的mime表示;公共程度較低的項目則很少見。
下面的代碼行顯示了各種各樣的擴充名、它們的uti(通過首選的utiforextension()擷取),以及從每個uti生成的mime類型(通過mimetypeforuti())。可以看到,其中有相當多的空白。當這些函數不能找到比對時,它們将傳回nil:
為了解決這個問題,用于這個秘訣的示例代碼包括了一個額外的mimehelper類。它定義了一個函數,傳回所提供的擴充名的mime類型:
nsstring mimeforextension(nsstring extension);
它的擴充名和mime類型源于apache software foundation,它将其清單放入公共域中。對于用于這個秘訣的示例代碼中的450個擴充名,ios傳回了全部450個uti,但是隻會傳回88個mime類型。apache清單把這個數字增加到230個可識别的mime類型。
2.1.3 測試順應性
使用uttypeconformsto()函數測試順應性。該函數接受兩個參數:一個源uti和一個要比較的uti,如果第一個uti順應第二個uti,就傳回true。可以使用這個函數來測試一個更具體的項目是否順應一個更一般的項目。相等性測試則使用uttypeequal()。下面顯示了一個示例,說明了可能如何使用順應性測試,确定檔案路徑是否可能指向圖像資源:
2.1.4 擷取順應性清單
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描述(kutimportedtypedeclarationskey和kutexportedtypedeclarationskey)、與uti相關聯的圖示資源(kuttypeiconfilekey)、指向描述類型的頁面的url(kuttypereferenceurlkey),以及為uti提供版本字元串的版本鍵(kuttypeversionkey)。
使用傳回的字典向上通過順應性樹來建構一個數組,表示給定uti順應的所有項目。例如,public.mpeg類型順應public.movie、public.audiovisual-content、public.data、public.item和public.content。通過conformancearray函數将這些項目傳回為一個數組,如秘訣2-1所示。
秘訣2-1 測試順應性