[SwiftUI] [Swift] iOS で Packaged Document を使う (その1 Packaged Document を定義して実装する)

SwiftUI

iOS アプリで パッケージ型のドキュメントを使う方法を説明します。

Apple も推していますので、iOS デバイスでも Files 経由で使う ドキュメントベースアプリケーション が普及してくるかと思います。

開発する側視点でも複数のタイプの情報を1つのドキュメントファイルにまとめるよりパッケージ型のドキュメントにしておく方が、様々な処理が容易となります。

Packaged Document サンプル

以前、Apple から、Objective-C で記述され、UIKit ベースのサンプルが提供されていました。

Xcode12 でも動きました。ここからダウンロードできます。

今回は、Apple のサンプルと、Xcode12 が Document App として生成するテンプレートコードをベースに作成していきます。

サンプルアプリ概要

写真とテキスト情報を合わせて、ドキュメントに保存するアプリです。テキスト情報は、テキストファイル。写真の情報は、PNGファイルとして保存されます。
テキストファイル、PNGファイルは、パッケージの内部に保存されますので、アプリのデータファイルとしては、1つに見えます。

Pacakged Doc in Files

「Pacakged Doc in Files」

サンプルアプリ機能

サンプルアプリに実装されている機能は、以下の通りでした。

  • ドキュメントリストアップ/作成/削除/名称変更
  • テキスト編集
  • 写真選択(PhotoPicker を使って)

まだ、Files アプリが提供されていなかった時のサンプルなので、Files アプリの機能も実装されています。

サンプルアプリ内で、ドキュメントの作成や削除、名称変更が行えるようになっていますが、現在の SwiftUI で提供されている DocumentGroup を使って管理機能を提供するほうが、良さそうです。

つまり、SwiftUI アプリ側では、(Package 化された)ドキュメントの読み書きとテキスト編集/写真選択 の機能のみを実装することとします。

SwiftUI アプリ仕様

以下のような仕様で作ります

  • Document type は、Apple のサンプルを流用
  • DocumentGroup から開かれたファイルは、詳細ビューでテキスト編集と写真の選択が行える
  • サンプルアプリのドキュメント編集モードは廃止。(開いた時点で編集モードになっているという前提)

実装

プロジェクト作成

Xcode を起動し、以下の設定でプロジェクトを作成します。

  • Product Name: PackageDocSwiftUI
  • Interface: SwiftUI
  • Life Cycle: SwiftUI App
  • Language: Swift

Product Name は、変更可能です。変更した場合は、サンプルコードを適当に読み替えてください。

ドキュメント設定(Info.plist)

Apple のサンプルを参考に、Document と Exported Type ID を設定します。

define Document Type and Exported Type ID

「define Document Type and Exported Type ID」
SwiftUI[Swift] [iOS][MacOS] Document App を作る(その1:UTI と Document Type の定義)

ドキュメント設定(PackageDocSwiftUIDocument.swift)

以下が、完成コードです。

PackageDocSwiftUIDocument.swift
コード解説
  1. Info.plist でも定義したタイプを Swift 上でも定義します
  2. Package 内での保存に使われるファイル名を定義しています
  3. ドキュメントの initializer
  4. ドキュメントが Read できるタイプを定義しています。別途定義しなければ、同じタイプに対して Write もできることになります。
  5. Files アプリ上で ドキュメントをクリックした際に呼ばれます
  6. 保存するときに使用する FileWrapper を定義しています

ドキュメント読込の詳細(PackageDocSwiftUIDocument.swift)

ドキュメントの読込部分について詳細を説明します。(保存側を先に読んだほうがわかりやすいかもしれません)

PackageDocSwiftUIDocument.swift
ドキュメント読込 解説
  1. ドキュメントが開かれると ReadConfiguration を引数として init が呼ばれます。.file に ドキュメント全体の FileWrapper がセットされています
  2. ドキュメント全体の FileWrapper には、保存ファイル名をキーとして、テキストファイル用とイメージファイル用の FileWrapper が設定されています。ここでは、テキストファイル用の FileWrapper を取得し、FileWrapper から、テキストを読み込んでいます。
  3. テキストと同様に、イメージファイルから UIImage を読み込んでいます。(イメージは、optional としているため、保存されていなケースも考慮しています)
  4. 取得したテキストとイメージを使って、ドキュメントモデル(Note) を設定しています

ドキュメント保存の詳細(PackageDocSwiftUIDocument.swift)

PackageDocSwiftUIDocument.swift
ドキュメント保存 解説
  1. Package で保存するため、ドキュメント全体の FileWrapper は、このように初期化して作成します。Package 内に含まれる要素についての FileWrapper を追加していきます。
  2. テキストデータを保存するための FileWrapper を作成し、ファイル名を設定してから、ドキュメント全体の FileWrapper へ追加します。(後から、このファイル名をキーに取得できます)
  3. イメージデータを持っているならば、テキストと同様に、FileWrapper を作成し、ドキュメント全体の FileWrapper へ追加します。
  4. 必要な 下位の FileWrapper を設定した FileWrapper を返します。

途中まとめ: Package Document を使う iOS アプリの設定

Package Document を使う iOS アプリの設定
  • Document Type, Exported Type IDを設定する
  • UTType も定義し、FileDocument#readableContentTypes に設定する
  • FileDocument#init で、読み込み用の FileWrapper を設定する
  • FileDocument#fileWrapper で、保存用の FileWrapper を設定する

説明は以上です。 Happy Coding!

コメントを残す

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