Question: What is SwiftUI API for creating status bar menus?

Apple seems to use SwiftUI views in Battery & WiFi menus according to the accessibility inspector. Screenshot of a battery menu attached, also its view hierarchy.

[![Battery menu screenshot](https://i.stack.imgur.com/5vqXC.png)](https://i.stack.imgur.com/5vqXC.png)
[![View hierarchy of the battery menu](https://i.stack.imgur.com/bweVy.png)](https://i.stack.imgur.com/bweVy.png)

**EDIT:**

Posted the solution as a separate answer.

Answer: 
*Since this question received more attention lately, and the only reply doesn't fully solve the issue I would like to repeat the edited part of my question and mark it as resolved.*

*Edit2: Added an additional piece of code that allows using a SwiftUI view as the status bar icon. Might be handy for displaying dynamic badges.*

Found a way to show this in [swiftui](/questions/tagged/swiftui "show questions tagged 'swiftui'") without an annoying `NSPopover`. Even though I used AppDelegate's `applicationDidFinishLaunching` to execute the code, it can be called from any place of your app, even in a SwiftUI lifecycle app.

Here is the code:

```swift
func applicationDidFinishLaunching(_ aNotification: Notification) {
        // SwiftUI content view & a hosting view
        // Don't forget to set the frame, otherwise it won't be shown.
        //
        let contentViewSwiftUI = VStack {
            Color.blue
            Text("Test Text")
            Color.white
        }
        let contentView = NSHostingView(rootView: contentViewSwiftUI)
        contentView.frame = NSRect(x: 0, y: 0, width: 200, height: 200)

        // Status bar icon SwiftUI view & a hosting view.
        //
        let iconSwiftUI = ZStack(alignment:.center) {
            Rectangle()
                .fill(Color.green)
                .cornerRadius(5)
                .padding(2)

            Text("3")
                .background(
                    Circle()
                        .fill(Color.blue)
                        .frame(width: 15, height: 15)
                )
                .frame(maxWidth: .infinity, maxHeight: .infinity,  alignment: .bottomTrailing)
                .padding(.trailing, 5)
        }
        let iconView = NSHostingView(rootView: iconSwiftUI)
        iconView.frame = NSRect(x: 0, y: 0, width: 40, height: 22)

        // Creating a menu item & the menu to add them later into the status bar
        //
        let menuItem = NSMenuItem()
        menuItem.view = contentView
        let menu = NSMenu()
        menu.addItem(menuItem)

        // Adding content view to the status bar
        //
        let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
        statusItem.menu = menu

        // Adding the status bar icon
        //
        statusItem.button?.addSubview(iconView)
        statusItem.button?.frame = iconView.frame

        // StatusItem is stored as a property.
        self.statusItem = statusItem
    }

```

[![enter image description here](https://i.stack.imgur.com/yxft8.png)](https://i.stack.imgur.com/yxft8.png)
Inside the AppDelegate add the following code:

```
// Create the status item in the Menu bar 
self.statusBarItem = NSStatusBar.system.statusItem(withLength: CGFloat(NSStatusItem.variableLength))

// Add a menu and a menu item
let menu = NSMenu()
let editMenuItem = NSMenuItem()
editMenuItem.title = "Edit"
menu.addItem(editMenuItem)

//Set the menu 
self.statusBarItem.menu = menu

//This is the button which appears in the Status bar
if let button = self.statusBarItem.button {
    button.title = "Here"
}

```

This will add a Button with a custom Menu to your MenuBar.

[![enter image description here](https://i.stack.imgur.com/IbXjt.png)](https://i.stack.imgur.com/IbXjt.png)

**Edit - How to use SwiftUI View**

As you asked, here is the answer how to use a SwiftUI View.

First create a NSPopover and then wrap your SwiftUI view inside a `NSHostingController`.

```
var popover: NSPopover

let popover = NSPopover()
popover.contentSize = NSSize(width: 350, height: 350)
popover.behavior = .transient
popover.contentViewController = NSHostingController(rootView: contentView)
    self.popover = popover

```

Then instead of showing a NSMenu, toggle the popover:

```
self.statusBarItem = NSStatusBar.system.statusItem(withLength: CGFloat(NSStatusItem.variableLength))
if let button = self.statusBarItem.button {
     button.title = "Click"
     button.action = #selector(showPopover(_:))
}

```

With following action:

```
@objc func showPopover(_ sender: AnyObject?) {
    if let button = self.statusBarItem.button
    {
        if self.popover.isShown {
            self.popover.performClose(sender)
        } else {
            self.popover.show(relativeTo: button.bounds, of: button, preferredEdge: NSRectEdge.minY)
        }
    }
}

```

[![enter image description here](https://i.stack.imgur.com/usNL8.png)](https://i.stack.imgur.com/usNL8.png)