[SwiftUI][macOS] macOS で 共有メニューを使う方法

SwiftUI

過去に、iOS アプリ向けに共有メニューを使う方法を説明しましたが、macOS 向けには違う方法だったので、説明します。

環境&対象

以下の環境で動作確認を行なっています。

  • macOS Big Sur 11.2.1
  • Xcode 12.4

Share Service

共有メニューを、アプリ内に作成する方法を説明します。

iOS での方法は、こちら。(共有メニュー内に自分のアプリが表示される方法を説明しています。)
UIActivityViewControllerにActivityを追加する方法UIActivityViewControllerにActivityを追加する方法[Swift] iOS の共有メニューに追加できるアプリを作る(その1:アプリが表示されるまで)[Swift] iOS の共有メニューに追加できるアプリを作る(その 2:HostAppからデータを受け取るまで)[Swift] iOS の共有メニューに追加できるアプリを作る(その3:ContainingApp と App Extensionのデータ共有)

Share Service @ macOS

NSSharingServicePicker

アプリから、共有メニューを開くには、 NSSharingServicePicker を使用します。(ユーザーが共有対象に応じたサービスを選ぶことができます)

Apple のドキュメントは、こちら

Picker という名前の通り、ほとんど全自動でやってくれます。

しかし、SwiftUI から使おうとすると問題があります。

開くメニューの位置決めのために、NSView が必要となります。ですので、SwiftUI からだとそのまま使うのは難しいです。

stack overflow では、こんなやりとりが見つかりました。

AppKit から使うのであれば、NSSharingServicePicker を呼ぶ時の引数に、適切なオブジェクトを渡してあげれば終了です。

凝った表示を行いたいときには、以下の NSSharingService を使って、共有時の振る舞いをカスタマイズすることができます。

NSSharingService

AppKit での共有メニューには、この NSSharingService を使用します。

Apple のドキュメントは、こちら

実際には、NSSharingServiceDelegate を実装してカスタマイズしていくことになります。Apple のドキュメントは、こちら

SwiftUI からの利用

stack overflow にも簡易的な利用方法が載っていましたが、SwiftUI から使おうとすると、どうにかして NSView と組み合わせて扱う必要が出てきます。

例によって、NSViewRepresentable を使って、NSSharingServicePicker を wrap した SDSSharingServicePicker という View を作りました。

普通に NSViewRepresentable を使って wrap すると View 作成時に 共有オブジェクトまで作成する必要がありそうですが、作成にコストのかかるオブジェクトを処理したかったので、closure を渡して、実際に共有する時まで、オブジェクトの作成を遅らせるようにしています。

作成した SDSSharingServicePicker は、SDSSharingServicePicker です。

SDSSharingServicePicker
SDSSharingServicePicker

まとめ:macOS での 共有メニュー

macOS での 共有メニュー
  • macOS では、NSSharingServicePicker を使う。
  • 受け渡しの画面をカスタマイズするためには、NSSharingServiceDelegate を使う。
  • SwiftUI 用に NSViewRepresentable で wrap した View は、こちら

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

コメントを残す

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