[Xcode12][SwiftUI] Document App の理解

SwiftUI

     

TAGS:

⌛️ < 1 min.
Xcode12 からドキュメントベースアプリのテンプレートが大きく変わりましたので、説明します。
macOS での振る舞いを追記

テンプレートで作られる Document App のコード

まずは、Xcode が生成する Document App のコードの意味を説明します。

テンプレートで生成されるアプリは、TextEditor ビューを使ってテキストファイルを処理できるアプリです。

デフォルトでは、”Hello, world!”というテキストを持つファイルが生成され、クリックするとそのテキストを編集できる TextEditor のビューが開かれます。




登場人物

きちんと読もうとすると複雑なので、登場人物を最初に列挙します。

登場人物
  • DocumentGroup
  • FileDocumentConfiguration
  • FileDocument
  • FileWrapper
  • UTType

(struct) DocumentGroup

Apple のドキュメントは、こちら

使用すると、iOS 上の “Files” アプリのようなファイル管理画面が表示され、ファイル管理(作成、開く、削除)ができます。

newDocument の引数が、ドキュメントを新規作成するためのものです。

新規作成されれば、newDocument で作成されたものが渡されますし、DocumentGroup 上で既存ファイルが選択されれば、選択されたファイルが editor に FileDocumentConfiguration として渡されます。

(struct)FileDocumentConfiguration

Apple のドキュメントは、こちら

ドキュメントをラップして、アプリケーションからみた保存場所や、編集可能かどうか等の情報を取得・設定できるようにするための struct 。

ドキュメントそのものは、インスタンス変数 document に保持させて、アプリケーションから必要な情報の API を規定しています。

Document は、Binding<document> としても参照できるように定義されています。

なお、対象とする document は、(Protocol)FileDocument に準拠している必要があります。

(protocol)FileDocument

Apple のドキュメントは、こちら

注意点としては、Reference semantics ではなく、value semantics を想定していると明記されていることです。

init/fileWrapper が、読み込み・書き出しに相当しますが、引数に、ReadConfiguration, WriteConfiguration が登場します。

この2つの Configuration は、読み込み・書き出し用のFileWrapper と UTType を保持する struct です。

なお、readableContentTypes と writableContentTypes で読み込み・書き出しできるタイプを指定できます。 writableContentTypes は指定しないと、readableContentTypes と同じタイプとみなされます。

(class)FileWrapper

Apple のドキュメントは、こちら

ファイルからアプリケーション内にデータとして読み込んだり、アプリケーションのデータをファイルに書き出すためのクラスです。

(struct)UTType

Apple のドキュメントは、こちら

ファイルのタイプや拡張子情報を持つ struct です。text 等のタイプは、すでに定義されていますので、定義済みのタイプを使えば良いです。動画や音声についても多く定義されています。

SwiftUI [Swift] [iOS][MacOS] Document App を作る(その1:UTI と Document Type の定義)




アプリ実行時の動作

テンプレートで生成されるコードは、以下のような動きをします。

新規ファイル作成

Xcode12.3, iOS14.2, macOS 11.1 では、新規ファイル作成の際の動作が、iOS と macOS で異なりました。(ドキュメントには記載されていません)

iOS では、FileDocument.init が呼び出され、その後 FileDocument.fileWrapper が呼び出され保存された後に、init(configuration:) が呼ばれる。

macOS では、FileDocument.init が呼び出される。macOS ではセーブするまで fileWrapper は呼び出されない。init(configuration:) は、アプリからドキュメントを開く操作をするまで呼び出されない。

iOS では、メモリ上にのみ存在する時間を短くしたいように見えます。ホームボタン一押しで、アプリ切り替えられて戻ってこないかもしれませんし。

なお、ファイル作成操作後は、ファイル編集と同じ動作になります。

ファイル編集

# 普通は、こちらがアプリケーションの本体です
ファイル管理画面でファイルが選択されると、FileDocument#init(configuration:ReadConfiguration)が呼び出されて、アプリケーションのドキュメントとしてのデータ設定を行います。
そのあとは、ContentViewに渡されて、TextEditor のビューが開かれます。




まとめ

テンプレートのコードだけで、ドキュメントを扱うアプリに期待される多くの部分がカバーされていることがわかるかと思います。

ドキュメントアプリを自分で作るためには、アプリで扱うドキュメントをきちんと定義することが必要となります。

アプリの扱うドキュメントを定義するということでは、以下のステップが必要になります

ドキュメントの定義
  • アプリがドキュメントとして扱うタイプの設定 (UTType)
  • アプリのドキュメント定義作成(FileDocument)
  • 読み出し・書き込み用のFileWrapper定義作成

ドキュメントアプリでファイル管理を含めたいろいろな操作ができそうなので、ユーザーからみたアプリ実行環境としては、MacOS にずいぶん近づきそうです。

説明は以上です。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です