ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
Uniform Type Identifierの再導入
システムが特定のファイルを開く時、どのようにAppを決定しているのか、考えたことはありませんか? Uniform Type Identifierのフレームワークを理解すれば、Appの標準または独自のファイルフォーマットへのサポートを簡略化できます。新しいフレームワークやXcodeの使い方を学ぶことで 、Appがサポートする型を定義し、UTTypeを採用した際にパフォーマンスを圧倒的に向上させる方法を理解し、UTTypeをサポートする最新のAPIプラットフォームを再検討できます。
リソース
関連ビデオ
WWDC23
WWDC22
-
ダウンロード
“Uniform Type Identifiers”の 再導入ようこそ 私はジョナサン・グリンスパンです アップルのApp開発と エンゲージメント担当です 前回 Uniform Type Identifiersについて話したのは 2004年のWWDCです 随分 前の話ですが 昨日の事のように覚えています 2004年のラインアップは クールなデザインでした アルミ製ボディのPowerBook G4 カラフルなiPod Mini 素晴らしい映像体験を可能にした iMac G5です 常に進化しています それでも2004年から 長い年月が流れました
基本的な部分をおさらいします 初めにアップルOSが ファイルの種類を認識する方法です 次に新たな種類のファイルを OSに認識させる方法です 最後にiOS 14とmacOS Big Surの 新しいAPIを紹介します 様々なファイルと速やかに連携します 今回 初めて知る方にも役立つ情報です
誰でも持っていそうなファイルを お見せします iPad Miniを使うネコの写真です この画像を保存すると レギュラーファイルが作られます ディスクに保存されるバイト列を指す POSIXの用語です 後でファイルを開く際に ダブルクリックで表示されます 例えばプレビュー表示です ではOSはどのように JPEGを認識しているのでしょう テキストやMP3 Pagesのファイルと区別する方法は? ファイルはバイト列で構成されるので システムがファイルを認識する時は 中身を開けて読み取ると思うでしょう 実際にはこのような動作はしません とても効率が悪くプロセッサに 読み取り許可を求められるためです
OSが行う決定の多くは パス拡張子を基盤にしています 最後のキャラクタに従った caseに標準化されたサブストリングで 空白やコントロールキャラクタが 含まれないものです アップルのプラットフォームでは パス拡張子は見えませんが 当然 存在しています ファイルのパス拡張子を見れば その文字列からJPEGと確認できます
つまり“.jpeg”はJPEG画像を指します しかしJPEGには他のパス拡張子があります “.jpg”や“.jpe”などが有名です ウェブの場合は話が異なります ウェブサーバーは一般的に パス拡張子で認識しません 代わりにMIMEタイプを用います
JPEGの場合は“image/jpeg”です 複雑なものもあります あるサーバーは 非標準の“image/jpg”を用いています 5つの異なるメタデータが 同じファイルを表しています アップルのプラットフォームでは 問題ありません Uniform Type Identifierという 1つの文字列を用いて ファイルのフォーマットを認識するからです Uniform Type Identifierで JPEGを表すのは“public.jpeg”です ローカルでもウェブでも この1つで全てのJPEGに対応します ファイルの種類のプロパティは 階層構造になっています あらゆるJPEG画像は 抽象化された画像です PNGやTIFFなどの画像も同じです Uniform Type Identifierの場合 JPEGの型は より抽象的な画像の型に適合します この適合性が多重継承を可能にします SwiftやObjective-Cで プロトコルが動くのと似ています 具象クラスは様々なプロトコルから 継承できます 実際に見てみましょう “public.jpeg”があります そして全ての画像フォーマットを表す 抽象型の“public.image”があります しかし全ての画像フォーマットは バイト列で表すことができるので “public.image”は “public.data”に適合します ディスク上の全てのレギュラーファイルを表す 抽象型です どんな場所に保存されているバイト列でも 表せます 同様に“public.data”は “public.item”に適合します 全てのファイルやフォルダ シンボリックリンクの他に より難解なPOSIXのパイプも “public.item”で表されます 階層の上へ行けるように 下へも下れます JPEG以外にも “public.png”や“public.tiff”があります “public.image”にも サブタイプがあります しかし適合性階層の中にはありません 兄弟のようなものです 階層の上にある “public.data”に注目すると 適合性のある様々な型が見つかります コンピューターにあるファイルは バイト列で表せるからです “public.audio”は 音声データを表す抽象型です “public.text”は 判読可能なテキストを表す抽象型です “public.data”のサブタイプや “public.image”の兄弟もいます
多重継承はUniform Type Identifierで できるとお伝えしました 画像データは ユーザーの大事なコンテンツでもあり iCloud Driveに上げ AirDropで共有します “public.image”は “public.content”にも適合します ファイルシステムを 具体的に表していなくても サブタイプをユーザーの重要な情報と 教えてくれます
Uniform Type Identifierが ファイルを表す方法を説明しました ユーザーに関わることでは 一般的な使用法ですが 私たちのプラットフォームでは 別の使い方もします 例えばPasteboard contentの 正規型として使います 最終的にディスクに保存すれば コピー&ペーストできます ファイルとは関係のない 階層としても使います Uniform Type Identifierは 別のモデルのハードウェアを 認識する際にも使います 全てのMacが “com.apple.mac”に適合します 仮想化する場合は Uniform Type Identifierを使い コンピューターに関係のない階層に 参照することができます これが私たちのプラットフォーム上の 使い方です 多くのAppが 個々のデータフォーマットを維持し それぞれに独自の型があります 新しい型は どのように階層に加えるのでしょう? システムに宣言された型を使う時は簡単です CoreTypesと呼ばれるバンドルに 多くの型が含まれ /System/Library/CoreServicesに 入っています Info.plist内にある Uniform Type Identifierは 変更を加えなくても 作ったAppで参照できます しかし新しい型や 他のAppから借りた型は 初めにシステムに認識させます Uniform Type Identifierを 自分で作る必要があります
Uniform Type Identifierを 作るには命名規則があります 大文字と小文字を区別しないASCIIを使い com.example.fileのように Reverse-DNSで表します できれば説明的な識別子をお勧めします com.example.fileで デバッグするのは簡単ではありません com.example.imagetemplateや com.example.encrypteddatabase これらに似たものが理想的です アップルは識別子に プレフィックスや名前空間を備えています これらと同じ識別子は使えず システムにも認識されません
“public”はアップルの標準型を 宣言するために使われます 標準型が見当たらない場合は フィードバックアシスタントへ知らせてください
“dyn”はdynamicの省略で OSが互換性Shimを 生成する際に使われます 多くはOpaque文字列で OSリリースの際に変更可能です 値をハードコードしてはいけません 現在ではまれなケースで 認識不能なパス拡張子のファイルを 扱う場合のみ使います
“com.example”が表すのは Examplesやサンプルコードなどです そして“com.apple”は アップルが使います
Appにシステムが認識する型を加えるには 2つのステップを踏みます 初めに型の宣言です 型の宣言とは Appが型の存在を認めるということです しかし型は開けません 開くには 型をサポートする必要があります つまり“誰の宣言でも型を開く”という 意味です 2つのステップは異なるものです
型を宣言する時は インポートかエクスポートかを決めます 他の誰かが作った型や 他のAppで使われた型を使う場合は 型のインポートが必要です こうしてシステムに 型の存在と情報を伝えます 作ったAppがインストールされると 更に権限のある情報を提供できます 自作のAppに合わせて 新しい型を作った場合には エクスポートが必要です システムに “自分がこの型の管理者”と伝えます Core Typeの一部として システムに装備された型を使う場合 インポートやエクスポートは必要ありません システムは宣言を与えているので Uniform Type Identifierの型を すぐに使えます
Appで型の宣言を行い システムに開かせる方法をお見せします それでは飲食店向けの 私が作業中のXcodeを見てみましょう このAppはJSONで作成された 飲食店のメニューを読めます 私たちのAppでメニューを開くには 初めに型の宣言が必要です 自分たちで独自の型を作ったので まずは型をエクスポートします 初めにXcodeでプロジェクトを選択し 設定を開きます Appに該当するターゲットを選びます これはiOS Appですが macOS Appの場合も同じです 次にInfoタブに切り替えます Info.plistファイルのコンテンツを 表します Exported Type Identifierの セクションを展開し セクション下部の“追加”で 型を追加します 初めに追加するのは Uniform Type Identifierです
このデモで使うのは com.example.restaurantmenuです com.exampleはアップルのデモに 用いられます 一般的にはReverse DNSの名前が 使われます 例えばClarisという会社は com.clarisを使います Beatsであれば com.beatsbydreです 次に適合性について考えます
ファイルシステムのファイルを表す型は レギュラーファイルの場合 public.dataに適合する必要があります OSがファイルとして扱うディレクトリであれば com.apple.packageです この型はSwiftのJSONエンコーダを使い ディスクに保存されます つまりバイト列です レギュラーファイルや public.dataも同様です ここで選択を迫られます JSONデータが含まれるので JSONデータを読み取る全てのもので 読み取れます つまりpublic.jsonにも 適合する型です マニュアルでの編集が重要な型では 便利なプロパティです それ以外の型では実装の詳細を表すだけです public.jsonへの適合性を 型に追加します 他の開発者に使用してほしくなければ これらの実装の詳細を無視できます フォーマットの変更を 予定する場合も同じです このファイルはディレクトリと 相互的な関係にあるドキュメントなので public.contentへの適合性を 持たせます
型と関連付けるするため 名前を決めます
拡張子はファイルシステムと 型を結びつけ 適切な名前の付いたファイルが 型を持っているか識別します 3文字拡張子は1995年以降― 主要なプラットフォームベンダーで 求められていません 自由に決められますが 他の開発者の型と一致しないよう 注意します それでは長めの拡張子 “restaurantmenu”を使います “.”は要りまません OSがファイル名の作成時に 追加してくれます 読んで分かりやすい名前を付けると 良いでしょう このAppを“Restaurant”と呼び 拡張子はrestaurantmenuなので 単純に“Restaurant Menu”と 名付けました
InfoPlist.stringsファイルに ローカライズ可能です この文字列を ローカライズのキーに使えます 型を宣言したのでシステムに Appを開けることを伝えます Document Typeを展開します セクション下部にある“追加”で 型を追加します Exported Type Identifierより 簡単なセクションです 指定が必要なのは Appがサポートする― Uniform Type Identifierの リストです 柔軟性を持たせるため 複数の型を指定します 個々に入力します エントリーごとに 1つの型を入力するのをお勧めします これは個人的な好みです Uniform Type Identifierを フィールドに追加します
エントリーのハンドラの順位を 管理者に設定します この作業ステップを強く推奨します システムが適切なAppに ジョブを委ねるのを助けます 型を作った段階で管理者なのです macOSでは更にルールフィールドがあり エディタかビューアか どちらで開くか指定させてくれます エディタはファイルを開き 保存できますが ビューアは開くのみです Appは読み取りと書き込みができるので エディタを指定します Infoセクションの編集を終えます これでAppは Restaurant Menuを開けます SwiftUIやUIkit AppKitのコードを書き 文書を処理できるようにします ドキュメントベースAppの Swift UIでの作り方は WWDC20の“Build Document-Based Apps in SwiftUI”を見てください UIkit and AppKitでの ドキュメントベースAppの作り方は developer.apple.comで 公開しています
Appストアには 競合のCompy's Foodがあります 多くの飲食店が使うAppで 独自のフォーマットで保存します そのファイルもサポートするつもりです 他の開発者が作った型を借りるので インポートする必要があります Infoタブに戻り Imported Type Identifiersを 選択します 新しいSwiftUI Appを作ったので example typeのための エントリーが残っています コンテンツを 自分たちのデータに置き換えられます ターゲットに 既存のサンプル型がない場合 下にある“追加”をクリックします Compy's Foodに指定された Infoセクションに入力します ここにあるのはサンプルなので 競合相手の型をサポートする場合 相手のInfo.plistファイルの内容に 適合するようにします インポートされた型なので システムにCompy's Food Appの 情報を伝えます ユーザーが既にインストールしていれば システムは宣言を申請し 権限のあるものとしてエクスポートされます ファイルへのサポートを追加し ユーザーが望んだ時に このAppを選べるようにします Document Typeセクションに 戻ります
リストに個々のエントリーを作り 新しい識別子を追加しました
このエントリーが他と違うのは 型の管理者ではないからです 代わりにハンドラの順位を代役にします このAppで書き込みはできないので macOSのビューアに指定します システムはファイルを開けると 認識しました しかし競合Appを使うユーザーには 最適な選択ではないかもしれません 敬意を払うことが大切です コードの優位性を確信していても 管理者の型を順守することが大切です Restaurant Menuの型で 実践したように ファイルを読み込むには Swiftか Objective-Cで書く必要があります 詳しくはdeveloper.apple.comを 見てください 型を宣言し システムは サポートを認識したので 私たちのコードにある型を使ってみます Uniform Type IdentifierのAPIに 広く精通していると仮定して話します ディレクトリやURLファイルを記した プログラムがあります 各ファイルの Uniform Type Identifierがあるので 識別子のローカライズ ディスクリプションを記入します 画像ファイルであれば表示されます 音声データであれば スピーカーやAirPodsから再生されます ここにいくつか問題があります 文字列をCFStringに 型変換する必要があります UTTypeの機能を使うためです UTTypeCopyDescriptionから得た CFStringのライフタイムを マニュアルで管理します ここでうれしいお知らせがあります iOS 14とmacOS Big Surでは Uniform Type Identifierの 新たなフレームワークを開発しました 最高クラスの迅速さを Swiftにもたらします これまではCFStringを使っていましたが 型とプロパティを表すのに UTTypeを使えるようになります このコードを 新たなフレームワークに変換します
APIへのアクセス権を得るため フレームワークをインポートし URLプロパティの識別子を contentTypeに変更します その値はUTTypeのインスタンスです この構造体が Uniform Type Identifierを メタデータと共にカプセル化します 次に保持されない値を修正します
UTTypeにはローカライズ ディスクリプションのプロパティがあります このプロパティは 型の属性やグローバル関数を自然に扱えます プロパティの値は Xcodeに入れた文字列と対応します Appと同時にローカライズされます 次は別のグローバル関数 UTTypeConformsToです この関数は明示的な型変換が必要な CFStringを使います UTTypeにはconforms-toの メンバメソッドがあります では“.image”や“.audio”とは 何でしょう? この図を覚えていますか? 新しいフレームワークの設計時に システムに宣言された型や 古いAPIのCFString定数を確認しました それを新しいフレームワークに 定数として持ち込み 120以上の定数を定義しました 一般的なシステム定義型が 多く含まれます 先程 私たちのAppで型を宣言しましたが その定数を公開できたら良いと 思いませんか?
今日はその方法もお教えします 名前付きインポートと名前付きエクスポートを 宣言させるAPIがあります セマンティクスはそれぞれ少し違います 型のエクスポートとは “私が型を作りAppに権限を与える”という 意味です UTTypeのインスタンスを作り この型についての全ての情報を伝えます 型のインポートとは “他にこの型に詳しい者がいる”という 意味です 型の管理者は 違う宣言をするかもしれません その場合は一般的に 複数まとめて型を置き換えられます 皆さんの協力が必要です インポートした型を定数と宣言せず 静的変数と宣言します Appのインストールで宣言が変更されても 自動的にアップデートされた型を選択します
型に関する問題を検出するサポートを Xcodeに作りました インポートまたはエクスポートされた型が Info.plistにない時や 誤った初期化子を使った際に検出します サポートを改善するには 皆さんの意見が貴重なので フィードバックをください 多くのフレームワークがiOS 14と macOS Big Surをサポートしています Foundationには URLプロパティがあり 文字列やURL UTTypeのインスタンスを基にした― ファイル名を生成する ユーティリティもあります SwiftUIには UTTypeへの詳細なサポートがあります Pasteboardや Drag and Drop APIの― onDropのイベントハンドラなどで 使われています
ドキュメントベースAppについての SwiftUIのサポートは UTType向けに設計されています WWDC 20の― “Build Document-Based Apps in SwiftUI”で説明しています
AppKitやNSWorkspaceを使う場合 UTTypeのアイコンを用意しています NSOpenPanelとNSSavePanelも UTTypeをサポートしています UIkitがUTTypeをサポートするのは ドキュメントピッカーや ドキュメントブラウザです Core Spotlightであれば UTTypeから属性集合を作れます UTTypeをサポートしないAPIも 多くあります その場合は対処が必要ですが 難しくありません Uniform Type Identifierを APIにパスするには UTTypeの識別子のプロパティを CFStringに型変換します Uniform Type Identifierを UTTypeに変換する際は CFStringから文字列に型変換し UTTypeを初期化します これは失敗可能イニシャライザなので nilの確認を忘れないでください
Objective-Cでも考えは同じです UTTypeの識別子を CFStringRefに型変換するか CFStringをNSStringに型変換し UTTypeを作ります 今回はシステムがメタデータから ファイルの型を抽出する方法と アップルが情報を カプセル化する方法を説明しました 型の作り方や宣言の手順の他に 複数のAppで共有される型の扱い方を 学びました Uniform Type Identifierの 新しいフレームワークを使い 型を相互的に扱う オブジェクト指向の方法を紹介しました この知識を参考に 新しいAppを作ってみてください ありがとうございます
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。