
昨日に引き続き博多で勉強会に参加しています。
午前中は
に参加して、午後は
こちらのイベントで登壇してきました。
発表資料
macOS Catalystについて
WWDC 2019にてmacOS Catalystが発表され、iPadアプリをmacOSアプリ化することができるようになりました。
UIKitが利用できるのでこれまでiOSアプリを開発してきた技術がそのまま利用が可能になります。
少ない工数で配布できるプラットフォームが増えるのでビジネス的にもチャンスが広がるかと思います。
iPadOS向けアプリをmacOS Catalyst化する方法
XcodeのGeneralタブのDeployment InfoでMac(requires macOS 10.15)にチェックを入れるだけでmacOS向けにビルドすることができます。

iOSとmacOSで知っておくべき違い
- タイトルバー(titleBar)

 - ツールバー(toolbar)

 - Touch Bar

 - メニュー(menu)

 
などです。 今回はメニューにフォーカスを当ててみます。
実装方法
UIResponderにbuildMenu(with:)というメソッドがあるのでAppDelegateでオーバーライドします。
#if targetEnvironment(macCatalyst) override func buildMenu(with builder: UIMenuBuilder) { super.buildMenu(with: builder) // TODO: build your menu } #endif
基本的にアプリを起動したタイミングか右クリックメニュー(contextMenu)が表示される際に呼ばれます。
ドキュメント: https://developer.apple.com/documentation/uikit/uiresponder/3327317-buildmenu
UIMenuBuilderにはsystemというプロパティがあり、その値をみてどのようなメニューを表示するかをハンドリングすることができます。
| UIMenuSystem | 定義 | 
|---|---|
 .main  | 
アプリ起動時に渡される。アプリ全体のメニューを構築する際に利用する。 | 
 .context  | 
右クリックメニュー(contextMenu)が表示される際に渡される。 | 
https://developer.apple.com/documentation/uikit/uimenusystem
UIMenu
メニューを構成するクラスです。タイトルや画像を設定することが可能です。
childrenにはUIMenuElementを継承しているクラスを入れることができるので再帰的にメニューを作っていくことが可能です。

この ファイル 編集... もそれぞれが UIMenu です。
https://developer.apple.com/documentation/uikit/uimenu
UIMenu.Identifier
メニューを識別するための一意な値です。
macOSで定義されているものもありますし、独自で定義することも可能です。
UIMenuBuilder
メニューの追加・削除・入れ替えを命令するクラスです。
UIMenu.Identifierを起点として追加や入れ替えをすることが可能です。
例えば.fileをreplaceすればメニュー丸ごと入れ替えることができます。
https://developer.apple.com/documentation/uikit/uimenubuilder
UIAction
クロージャーの実行が可能なクラスです。
UIMenuElementを継承しているのでUIMenuのchildrenに追加することができます。
UICommand
セレクターの実行が可能なクラスです。
UIActionと同じくUIMenuElementを継承しているのでUIMenuのchildrenに追加することができます。
UIKeyCommand
キーボードショートカットの実現を可能にするクラスです。
前述したUICommandを継承しているのでUIMenuのchildrenに追加することができます。

https://developer.apple.com/documentation/uikit/uikeycommand
canPerformAction(_:withSender:)
渡されたaction: Selectorが実行可能かどうかをBoolで返すメソッドです。
メニュー自体の活性、非活性を判定します。
https://developer.apple.com/documentation/uikit/uiresponder/1621105-canperformaction
注意点
UIMenuSystem.mainが渡されるのはアプリの起動時のみで、しかも必要なインスタンスが生成されていない可能性が高いので事前にメニューを構築する必要があります。
UIKeyCommandを何度も生成するのは無駄なので静的に保持しておくのが良さそうです。UIMenuのaction: Selectorは重複すると1つ目しか表示されないので、重複しないように設計する必要があります。同じメソッドを指定して、渡されたオブジェクトを判定して処理を分けたりする実装ができません。
まとめ
macOSアプリではメニューも大事な要素だなと感じました。
ただ、キーボードショートカット(UIKeyCommand)をメニューに入れることができるので、キーボードショートカットを実装しつつメニューを作っていくというのも良い選択肢かなと思いました。
Appleのサンプルコードもあるので参考に見てみるのをおすすめします。
macOS Catalyst化していくには避けて通れない道なので細かいメニューを作り込んでより良いmacOS Catalystアプリを作っていきましょう。
PR
この度macOS Catalystに必要な要素の実装方法をまとめた電子書籍を作成しました。
有料ですがここまでまとまった情報が日本語では見当たらなかったので個人的にはいい本が書けたと思っています。

積極採用中!!
子育て家族アプリFammを運営するTimers inc.では、現在エンジニアを積極採用中!
急成長中のサービスの技術の話を少しでも聞いてみたい方、スタートアップで働きたい方など、是非お気軽にご連絡ください!
採用HP: http://timers-inc.com/engineerings