cockscomblog?

cockscomb on hatena blog

iOS/OS X 用ライブラリ UTIKit を OSS でリリースしました

UTI

UTI とは Uniform Type Identifier のことで、iOSOS X の世界で、ファイルなどの種類を表すために用いられる文字列です。

UTI の実例として、画像一般を表す public.image や、そのサブタイプで JPEG 画像を表す public.jpeg などがあります。iOSOS X で利用されるほとんどのファイル形式には対応する UTI があり、例えば Keynote ファイルは com.apple.iwork.keynote.key などとなります。もちろんサードパーティも例外ではなく、Adobe Photoshop のファイルは com.adobe.photoshop-image となり、Microsoft Word の docxorg.openxmlformats.wordprocessingml.document です。

iOSOS Xフレームワークは、ファイルの種類を表すのにこの UTI を利用することが多くあります。例えば Photos.framework から画像データを得たいというとき、PHImageManagerrequestImageDataForAsset(_:options:resultHandler:) メソッドを利用します。この resultHandler((NSData!, String!, UIImageOrientation, [NSObject : AnyObject]!) -> Void)! という型のクロージャで、クロージャの第2引数はドキュメントを読むと dataUTI となっています。すなわち、画像データの種類が UTI として得られます。

ところで、この UTI から拡張子MIME type や拡張子を取得するにはどうすればよいのでしょうか。画像をサーバーにアップロードするときには MIME type が必要かもしれません。例えば public.jpeg だったら image/jpeg という風な対応を丁寧に処理しても良いかもしれませんが、そもそも iOSOS X にはそういった関数が備わっています。func UTTypeCopyPreferredTagWithClass(inUTI: CFString!, inTagClass: CFString!) -> Unmanaged<CFString>! を利用することで UTI から MIME type や拡張子が得られます。

let mime = UTTypeCopyPreferredTagWithClass("public.jpeg", kUTTagClassMIMEType).takeRetainedValue() // => "image/jpeg"

let ext = UTTypeCopyPreferredTagWithClass("public.jpeg", kUTTagClassFilenameExtension).takeRetainedValue() // => "jpeg"

またここでは紹介しませんが、逆に MIME type や拡張子から UTI を得る関数もあります。非常に便利ですが、ごくたまにしか使わないので忘れがちです。筆者は毎回のように忘れて、過去のプロジェクトや IRC のログを検索して思い出します。

UTIKit

ということで、このような UTI に関連した処理を利用しやすくするラッパーライブラリが、UTIKit です。これを利用すると上記の処理が以下のようになります。

UTI("public.jpeg").MIMEType // => "image/jpeg"

UTI("public.jpeg").filenameExtension // => "jpeg"

ごく短くなる上に、インターフェースもわかりやすいですね。

もちろん MIME type や拡張子から UTI を得るのも簡単です。

let jpeg = UTI(MIMEType: "image/jpeg")

let jpeg = UTI(filenameExtension: "jpeg")

Equatable を実装しているためこれらふたつは同値です。

UTI(MIMEType: "image/jpeg") == UTI(filenameExtension: "jpeg") // => true

また、public.jpegpublic.image に従っているので、switch を利用して以下のように書けます。

switch UTI("public.jpeg") {
case UTI("public.image"):
    println("JPEG is a kind of images")
default:
    fatalError("JPEG must be a image")
}

これらのように、UTI が Swift ライクに扱えることがわかります。

ご利用方法

CocoaPods 0.36 以降でインストールできます。Podfile に以下の行を書き足しましょう。

pod "UTIKit"

また Carthage でもインストールできるかもしれません(試してない)。

MIT ライセンスです。どうぞご利用ください。

To Do