swiftmacosmacos-montereynsstatusitemnsstatusbar

NSStatusItem icon randomly dissappearing


I'm trying to figure out a weird problem that's happening with my menu bar app. It would run perfectly fine for a couple of hours or even days but would randomly disappear from the menu bar.

In activity monitor, it's still running in the background. There's a global keyboard shortcut in the app to show the window and it brings out the app no problem but the menu bar icon is still missing.

I'm on macOS Monterery 12.2.1

StatusBarController

class StatusBarController {
    private var statusBar: NSStatusBar
    private var statusItem: NSStatusItem
    public var popover: NSPopover
    private var eventMonitor: EventMonitor?
    
    init(_ popover: NSPopover)
    {
        self.popover = popover
        statusBar = NSStatusBar.init()
        statusItem = statusBar.statusItem(withLength: 28.0)
        
        if let statusBarButton = statusItem.button {
            statusBarButton.image = #imageLiteral(resourceName: "link")
            
            statusBarButton.image?.size = NSSize(width: 18.0, height: 18.0)
            statusBarButton.image?.isTemplate = true
            
            statusBarButton.action = #selector(togglePopover(sender:))
            statusBarButton.target = self
        }
        

    }
.......}

App Delegate

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
    var popover = NSPopover.init()
    var statusBar: StatusBarController?
    

    func applicationDidFinishLaunching(_ aNotification: Notification) {
        // Create the SwiftUI view that provides the contents
        let contentView = ContentView()

        // Set the SwiftUI's ContentView to the Popover's ContentViewController
        popover.contentViewController = MainViewController()
        popover.contentViewController?.view = NSHostingView(rootView: contentView)
        popover.animates = false
     
        
        KeyboardShortcuts.onKeyUp(for: .triggerPopover, action: {
            self.statusBar?.togglePopover(sender: self)
        })
        
        // Create the Status Bar Item with the Popover
        statusBar = StatusBarController.init(popover)
    }


    
}

Solution

  • From Status Bar Programming Topics:

    A system-wide status bar resides at the right side of the menu bar and is the only status bar currently available.

    NSStatusBar.init() doesn't return the system status bar. Use NSStatusBar.system instead.