Dockメニューに動的なアイテムが表示されないのはXcodeのビルド経由の起動だから
Dockのアプリアイコンから開けるメニューには、アプリが提供するコマンドや、開いているウインドウの一覧が表示される仕組みがあります。ですので、macOSアプリを開発していると、Dockメニューに何か好きなメニュー項目を置きたくなることがあります。あるいはユーザーとして、開いているウインドウをそこから選択したくなることも稀にあるかもしれません。例えばMail.appなら次のような具合のインターフェイスになります。
これの実現には、NSApplicationDelegateのapplicationDockMenu(_:)
を使います。
AppDelegateでこのメソッドを実装して、用意したNSMenuオブジェクトを返すだけのシンプルなものです。Nibを使う場合にはInfo.plistにAppleDockMenu
をキーとしてNib名を入れとけなどの情報もありますが、基本的にはコードで十分だと思いますので、上記メソッドのみで対応可能であるはずです。
しかし、Xcodeで自分のアプリをデバッグしている最中にそのDockメニューを開いてみても、用意したはずのNSMenuが何も表示されないどころか、開いているウインドウを表すアイテムすらも表示されないことがあります。
何かがおかしいです。
原因に見当がつかず、Document-based Appではないから、とか色々調べてみたものの、なぜか私のビルドだけこの現象が起きていました。
そのようにして何ヶ月も悩んでいたのですが、ふと、Xcodeのビルド経由ではない、普通の方法で自作アプリを起動してみたところ、なんと問題なくDockメニューが表示されることに気がつきました(なんでやねん!)。
発現条件
Xcodeのビルド経由のアプリ起動だと、Dockメニューに動的なアイテムが表示されない(ことがある)。
対策
- Edit SchemeのRunところで Wait for the executable to be launched にチェックを入れて、Build & Runの際には自分でアプリを起動する
- Xcodeのビルド経由ではDockメニューのデバッグを諦める
原因はよくわからないのですが、Dockに並ぶアプリアイコン = DockTileはアプリ本体とは別プロセスで動いているらしいので(DockもしくはDock Extraだと考えられる)、Xcode経由の起動だとプロセス間通信がうまくいっていないのではないか? と考えました。
OSのバグと言えばそうなのかもしれませんが、とりあえずフィードバックはしておきつつも、一旦は上記の対策で凌ぐしかなさそうです。ただプロダクション版には影響がないため、デバッグのやり方だけを工夫する必要があります。
Discussion