能登 要

札幌在住のiOSアプリ開発者。SwiftUI により分割されたデバイス間を縦横にやりとりできる考え方に転換しています。

iOSアプリ開発者。2009年のiPhoneアプリ開発開始時期から活動。開発言語のアップデートの中でSwiftUIおよび周辺技術に着目中。

macOSアプリからアプリが対応するファイル形式定義を入手する - (macOS, iPadOS)

端的にいうと

Apple向けドキュメントアプリ開発者向けのHowToメモ。既存アプリが対応しているファイル形式を、拡張子を糸口として必要なファイル形式情報を調べることができる。

概要

SwiftUIではmultiplatform 対応のドキュメントベースアプリを作成できる。既存アプリが対応しているファイル形式にも対応可能だがそのためにはファイル形式定義を取り込む必要がある。ここでは拡張子から手軽にファイル形式定義を調べる方法を説明していく。

必要なファイル形式定義について簡単に説明しておくと、UTI(Uniform Type Identifier)と呼ばれる定義で2004年ごろにAppleが公開し今日に至っている。ファイルの固有IDの他、MIME形式、拡張子のバリエーション、ファイル形式の参照先などファイル形式に必要な情報をを内包し、Appleが提供するOSとその上で動くアプリ間で連携する上で必要な定義として定められている。

Uniform Type Identifier

Uniform Type Identifiers という末尾が複数形名称のフレームワークも存在しているので注意。

1) 準備

目的のファイル形式を開くことができるアプリケーションを確認する。ファイルとオープン(Command+O)で開くことができるアプリは何かを確認。ファイルを開くことができたアプリをファインダーから選択できる状態とする。

一般的なアプリは、アプリケーションフォルダに格納されている。ファイルダーを開きCommand+Aでアプリケーションフォルダへ移動するとアプリをファイルダー上で確認することができる。アプリによってはアプリケーションフォルダに格納されていない場合がある(Xcodeに含まれるユーティリティアプリなど)、アプリケーションで見つからない場合はファインダーの検索からアプリケーションを検索、見つけたアプリケーションのコンテキストメニューを開きアプリケーション名で検索すると見つけることができる。

2) 拡張子からファイル形式定義IDを調べる。

拡張子を糸口にファイル定義IDを見つける。以下のBlogのコードからファイル形式定義IDを取得できる。

Mac や iOS でファイルの種類を表す識別子 Uniform Type Identifiers を拡張子から調べる(Swiftで1行で出来る) - niwatakoのはてなブログ

上記Blog中に以下のコードが含まれているので目的の拡張子に変更して結果を確認する。

import Foundation

if let str = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, "[ここに拡張子]" as CFString, nil)?.takeUnretainedValue() {
    print("\(str)") 
}

macOS上だと新規プロジェクトをCommandlineを指定してプロジェクト作成。

プロジェクト作成後main.swiftを置き換えて実行するとmacOSにインストールしているアプリで拡張子に対応しているアプリがあればファイル定義IDをXcodeのログ画面に出力して終了する。

macOS command line tool

3) アプリケーション内のinfo.plistを調べる

ファイダー上から1で準備したアプリのコンテキストメニューを出し、パッケージの内容を表示をタップする。Context/info.plist ファイルをXcodeで開く(Xcodeアプリアイコンにドロップ)。

2で得られた文字列を開いたinfo.plistから検索を実行する。Xcodeの検索はinfo.plistの階層構造から一致する文字列を見つける。検索の際、完全に一致しているか注意する。

検索で完全に一致する項目は2項目見つかる。

合致した項目のトップレベルの要素はDocument types、Exported Type IdentifiersもしくはImported Type Identifiersの3つのうちいづれかになるが、Exported Type IdentifiersもしくはImported Type Identifiersに含まれるものがファイル形式定義となる。

見つけたファイル形式定義はクリップボードにコピーできる。見つけた項目の親階層を辿り、

Item nn(ファイル形式名)

を選択しコピーするとファイル形式全体を入手したことになる。

Xcodeのプロジェクトファイル形式定義を例にすると以下のような情報が手に入る(2021年現在)。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>UTTypeIcons</key>
	<dict>
		<key>UTTypeIconBackgroundName</key>
		<string>xcode-project-fill</string>
	</dict>
	<key>UTTypeIdentifier</key>
	<string>com.apple.xcode.project</string>
	<key>UTTypeConformsTo</key>
	<array>
		<string>public.composite-content</string>
		<string>com.apple.package</string>
	</array>
	<key>UTTypeTagSpecification</key>
	<dict>
		<key>public.filename-extension</key>
		<array>
			<string>xcodeproj</string>
			<string>xcode</string>
			<string>pbproj</string>
		</array>
	</dict>
	<key>UTTypeReferenceURL</key>
	<string>http://developer.apple.com/tools/xcode/</string>
	<key>UTTypeDescription</key>
	<string>Xcode Project</string>
</dict>
</plist>

4) 何に使うの?

macOSやiPadでドキュメントアプリを作ったないし作りたい開発者ではないと使い道がないノウハウ

3でコピーしたファイル形式定義を自作アプリに組み込むことができる。ファイル形式定義はOS側にファイル形式定義を伝えるだけなので注意が必要。OSがファイルを開くことができるアプリと認識させるためにはinfo.plistにDocument typesが別途必要なので注意してほしい。