Mac Catalyst + SwiftUIでiOS / macOS両対応のアプリをリリースした話

久しぶりに新しいアプリを開発することになった。ちょうどCatalinaが正式リリースされたタイミングでもあったので、Mac Catalystを使ってiPad / Macの両対応を目指すことにした。また、コードベースでUIを記述することができるSwiftUIを使用して、iPad / Macで必要に応じて効率的にUIの分岐を行えるようにした。

先に言いたいことをまとめると下記のようになる。

  1. SwiftUIは、便利だが多少難易度が高い
  2. Mac Catalyst + SwiftUIの組み合わせではさらに難易度が上がる
  3. ただし、乗り越えれば超効率的なiOS / macOSの両対応が実現できてすごい

実際にリリースしたアプリの紹介

アプリの詳細についてはこの投稿の本題とはあまり関係がないので省略するとして、このアプリはMac Catalyst + Swift UIを使って開発されており、iPad / macOSの両方で動作する。

下記の部分のみはiOSとmacOSでコードを分けたが、それ以外の部分はOSによる処理の分岐なしで、完全に一つのコードで両アプリが動いている。

  1. iOSでは「フォトライブラリから動画を読み込む」ボタンを表示するが、macOSでは表示しない
  2. iOSでは出力された動画をUIActivityViewControllerを表示してDropboxなどの他のアプリに渡せるようにするが、macOSでは「ファイルに保存」ダイアログを表示する
  3. 字幕の「スタイル」編集画面で、iPadでは要素をつめて表示したり一部ポップアップ表示したりする

いずれも、分岐しなくてもアプリとして使うこと自体はできるが、各デバイスの使われ方を考慮した際に挙動を変えた方が使い勝手が良くなりそうだったので、分岐させた。

9月ぐらいから開発を始めて、本当はもっと早くリリースできるかなと思っていたのだが、色々と苦戦して12月末にようやく最初のバージョンをリリースできた。以降、どのようなところで苦戦していたのかを記していく。

SwiftUI

大前提として、SwiftUIによるUI開発・管理はStoryboard時代に比べてとても先進的で便利になったと思う。一度慣れてしまうと、SwiftUIを使わないUI開発に戻るのはなかなか辛い。ただし、最低限使えるようになるまでは結構苦労した。

Web上の情報が古い問題

SwiftUIを勉強する上で、最初に厄介だったのがこの問題だった。SwiftUIは6月のWWDCで発表されたのだが、9月に正式版がリリースされるまでの間に結構色々な仕様の変更が行われている。

公式ドキュメントを読むだけで完全に使い方やパターンを理解できれば良いのだが、なかなかそうもいかない場面も多く、困ったときは検索をしてみるのだが、ウェブ上には6月のベータ版時点での仕様に基づいた情報が非常に多く、これには結構惑わされた。どれが古い仕様で、どれが最新の仕様なのか、ある程度理解が進めば判別ができるのだが、最初に勉強するタイミングではその判断に苦労した。とりあえず、最新の公式ドキュメントを徹底的に読むことと、ウェブ上の情報は「古い仕様かも?」という目で読んでいった方が良い。

コードとエラーの内容が直接リンクしない問題

SwiftUI上でListを使うと内部的にはUITableViewが生成される。そこでエラーが発生するとエラーログにはUITableViewのエラーとして表示される。ListとUITableViewの関係性を理解していないと原因の特定ができない。

SwiftUIだけでは解決できない問題

例えば、ボタンが押されたら特定のテキストフィールドに自動でフォーカスが移動するようにする、みたいな処理はSwiftUIだけでは実現することができない。また標準のTextFieldでは、日本語の入力が正しく受け付けられなかったり、複数行の入力に対応させることができない。このような場合には、UIViewRepresentableを使って自前でViewを実装する必要があるのだが、この部分の実装は複雑になりがちで多少苦労した。

コンパイラが原因と関係ないところでエラーを返す問題

SwiftUIでは、コードに問題があるとビルド時にXcodeがエラーを表示してくれるのだが、なぜか本来のエラー原因と全然関係がないところで、全然関係がないエラーが表示されることがある。ウェブ上では、同じような症状に遭遇した人の情報がちらほらあるので、おそらくビルドキャッシュの問題か、コンパイラの問題だと思うのだが、残念ながら原因と対処法はよくわかっていない。そういう時は「別の箇所が原因かも?」という疑いの目でデバッグをしていくことになるのだが、なかなかこの作業は難易度が高く効率が悪かった。

Mac Catalyst

ファイルを開くダイアログを出せない問題

これに関しては、詳細をこちらに分けて記述した。Catalystを使ってmacOSアプリを作る場合は、macOS固有の機能を直接呼び出すことができない。ファイルを開くダイアログを表示するにも、NSOpenPanelではなくUIDocumentPickerViewControllerを使用する必要があるのだが、iPadでは問題なく動作するものが、macOSではなぜかうまく動かないなどの問題が発生し、対応に苦労した。

リリース方法がわからない問題

リリースに関しても、情報が少なく苦戦した。先に結論から書くと、CatalystアプリをリリースするにはApple DeveloperのCertificates, Identifiers & Profiles画面で、iOSアプリ用のIdentifierのCapabilitiesでMacにチェックを入れた上で、Automatic Code Signingで署名、App Storeへのデリバリーを行えば良い。このやり方はWWDCのビデオでは説明されていたのだが、公式ドキュメント上ではこの手順を見つけることができなかった。

自分の場合は、運悪く下記の現象にもハマってしまっていた。

https://stackoverflow.com/questions/46148523/profile-doesnt-match-the-entitlements-files-value-for-the-application-identifi

投稿の説明通り、CapabilitiesでiCloudを一旦ONにした上でOFFにしてビルドしなおしたところ、最終的に無事アプリをAppStoreに提出することができた。同様の現象にハマってしまった人は試してみて欲しい。

リリース後の開発について

上述の通り、開発からAppStoreでの配信までは、結構苦戦をしたので思ったよりはリリースまで時間がかかってしまった。

ただ、一旦iOS版 / macOS版のリリースを完了してからは、SwiftUI / Mac Catalystの良さをすぐに実感することになった。今回リリースしたアプリは、コードとしてはそこそこ複雑でUIの要素も多いのだが、冒頭に書いた通りiOS版とmacOS版で処理を分けている箇所は全体のうちでUI関連の3箇所しか存在しない。おかげで、アップデートの効率が非常に良い。SwiftUIで、Storyboardと違ってOSによる内容の分岐を最小限の工数でかけることによる、UI開発の効率アップも非常に大きい。

また、基本的にはmacOSで動作確認したものはほぼそのままiOSで動作するため、macOSアプリとして開発を進めて、iPad実機やシミュレータは動作確認に使う程度で大丈夫、というのもありがたい。おかげで、出先でiPadを持っていない状態でも開発を進めていくことができる。

リリースまでの道のりは長かったが、リリース後は期待以上の世界が広がっていた。

Mac Catalyst + SwiftUIと仲良くやっていくには

いきなり組み合わせずに、それぞれちゃんと習得する

CatalystもSwiftUIもiOS / macOSのハイブリッドアプリを開発するにはとても有用な機能だし、組み合わせることで効果が最大化するのは間違いないが、それぞれ習得まではそこそこ学習が必要だ。この二つは組み合わせると更に学習の難易度が上がってしまうので、個別にある程度習得をしてから組み合わせに挑戦した方が良い。

まずは小さいアプリ開発で慣れる

いきなり大きなアプリをこの組み合わせで作るのはとても難易度が高い。そして、プラクティスを習得せずに今までのiOS / macOSアプリの感覚で設計をはじめてしまうとあとで大改修が必要になってしまう可能性が高い。

まずは、小さなアプリを開発し、リリースするところまでを経験してから大きなアプリの開発に着手した方が良い。自分の場合も、一つものすごく小さなアプリの開発・リリースを行ったが、その経験がとても役に立った。(それでも設計・構造は途中で何度も見直すことになった)

まとめ

Mac Catalyst + Swift UIの組み合わせは、普段iOS / macOSアプリの開発を行っていない自分にとってはなかなか難易度の高い挑戦になった。まだ世にまとまっているノウハウが少ないことや、組み合わせによって発生する問題などもあり、そこそこの経験と忍耐力が求められる。一方で、一度リリースできるレベルまでコードが出来上がってしまえば、その先は想像以上の生産性でiOS / macOSそれぞれのアプリをアップデートしていくことができる。

今後ノウハウの共有が進んだり、各技術の完成度が高まってくれば難易度は下がっていくだろうし、省コストでiOS / macOS両対応アプリを開発・運用できることのメリットは非常に大きい。ちょっと覚悟を決めたら、小さいアプリの開発から使って行ったら良いのでは無いかと思う。

Pocket

「Mac Catalyst + SwiftUIでiOS / macOS両対応のアプリをリリースした話」への2件のフィードバック

  1. 日本語でちゃんと読めるCatalystの記事、初めて見たと思います。大変参考になりました。ありがとうございました。

コメントを残す

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