はじめに
毎年 SwiftUI に期待しながら、ちょっと触ってみてまだ早熟かなと、ずっと距離を置いていたのですが、ある人言葉をきっかけにやっぱりそろそろ試してみようかなと思うようになりました。
個人的にはグラフィックやメディアを扱うアプリを扱う事が多いので、ちょっとメディアコンテンツのエディターみたいなものを冷やかして書いてみようかなと思いました。
想定するアプリをこんなものに想定してみます。
- iOS、または macOS のドキュメントベースのアプリとする
- データのサイズが大小さまざまの大量のテキストやイラストや動画や音声を扱うため、パッケージ(フォルダ)ベースのドキュメントとする
やってみた
さて、Xcode から Multiplatform > Application > Document App からドキュメントベースのテンプレートを選びます。Multiplatform からだと、SwiftUIベースのプロジェクトに勝手になります。
CFBundleDocumentTypesやUTExportedTypeDeclarationsそしてUTImportedTypeDeclarationsを設定して、ドキュメントをパッケージとして扱います。
そして、FileDocumentベースでMyPackageDocumentAppDocumentを実装します。まずはドキュメントを読み込むには次のメソッドを実装します。
init(configuration: ReadConfiguration) throws
func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper
さて、configuration.file でFileWrapperにはアクセスできますが、FileWrapper経由でディレクトリに直接アクセスする事はできません。
さて、気を取り直すとして、UIDocumentでは次のメソッドをオーバーライドして、ディレクトリに直接アクセスする事ができました。
override func write(to url: URL, ofType typeName: String) throws
override func read(from url: URL, ofType typeName: String) throws
さて、SwiftUIでは・・
「………」
FileDocumentはそもそもプロトコルでfunc read(from url: URL, ofType typeName: String)に相当する実装はできません。
まぁ、iCould Driveのような環境が出てきて、ドキュメントのディレクトリに直接アクセスしてくれるなという気持ちは分かりますが、ドキュメント内で大量のファイルをパッケージとして扱いたい場合に、これらを全てFileWrapperで包んで読み書きするのは無理筋そうなので、今回はここで詰んだという事になりそうです。
コード
今回の検証の為に書いたコードは以下のURLから取得できます。ドキュメントを保存すると無駄に巨大なバイナリファイルがパッケージ内に作られるので、動作確認後は書類は削除してください。
結論
特定のアプリの実装にSwiftUIを採用するにはまだ早すぎるようです。
環境
執筆時点での環境は以下の通りです。
Xcode: 13.2.1
Swift: 5.5.2
macOS: 12.2.1
iOS: 15.3.1