[macOS]メニューバーに常駐するアプリ
macOS13から利用できるMenuBarExtraを使用してSwiftUIでメニューバーに常駐するアプリを開発できるようになりました。
しかし、macOS12以前のmacOSでは、MenuBarExtraはmacOS13からの対応なのでMenuBarExtraを使用しない方法で、メニューバーに常駐するアプリを作ってみます。
確認した環境
- macOS 14
- Version 15.0.1
プロジェクトを作成
プロジェクトのテンプレートを選択
Xcodeでプロジェクトのテンプレートを選択しプロジェクトを作成します。
macOSのAppを選択して「Next」ボタンで次に進みます。
Product Nameを入力
プロダクト名を入力し「Next」ボタンで次に進むとプロジェクトが作成されます。
プロジェクトが作成される
作成時の状態
ビルドして実行
この状態でビルドして実行すると、デフォルトのHello, World! 画面が表示されます。
アプリケーションクラスをカスタマイズ
アプリケーションクラスを編集
アプリケーションクラスを編集ます。
修正前
import SwiftUI
@main
struct SwiftuiMenuBarExtraSampleApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
修正後
メニューに、Start、End、Quitの3つのメニュー項目を表示し、Quitを選択するとアプリケーションが終了するようにします。
import SwiftUI
@main
struct MenuBarSampleApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var delegate
var body: some Scene {
Settings {}
}
}
class AppDelegate: NSObject, NSApplicationDelegate {
var statusItem: NSStatusItem!
func applicationDidFinishLaunching(_ notification: Notification) {
statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
let image = NSImage(systemSymbolName: "camera", accessibilityDescription: nil)!
statusItem.button?.image = image
let menu = NSMenu()
let startMenuItem = NSMenuItem.init(title: "Start", action: #selector(start), keyEquivalent: "1")
menu.addItem(startMenuItem)
let endMenuItem = NSMenuItem.init(title: "End", action: #selector(end), keyEquivalent: "2")
menu.addItem(endMenuItem)
let quitMenuItem = NSMenuItem.init(title: "Quit", action: #selector(quit), keyEquivalent: "q")
menu.addItem(quitMenuItem)
statusItem.menu = menu
}
@objc func start() {
print("start")
}
@objc func end() {
print("end")
}
@objc func quit() {
print("quit")
NSApplication.shared.terminate(self)
}
}
実行してみる
実行するとメニューバーに、cameraアイコンが表示されます。
メニュー項目には、Start、End、Quitが表示されます。
Quitを選択するとアプリケーションが終了します。
常駐アプリの設定
このままではDockやアプリケーションスイッチャーにアプリアイコンが表示されてしまいます。
メニューバーのみ表示される常駐アプリにする場合は、Application is agent (UIElement)
を設定します。
TARGETの設定
TARGETの設定でApplication is agent (UIElement)
を追加しvalue
にYES
を設定します。
Application is agent (UIElement)
を設定すると、Dockやアプリケーションスイッチャーにアプリアイコンは表示されなくなりました。