Creating a Menu Bar App

If you look in the upper right corner on the menu bar of any Macintosh, you’ll see plenty of icons that represent volume control or access to your Time Machine backups. If you want to create a little utility that can be accessed through the menu bar, you need to create a menu bar app.

Unlike a regular macOS program, a menu bar app does not display a list of pull-down menu items, nor does a menu bar app display an icon on the Dock when it’s running. All a menu bar app needs to do is display an icon or menu title on the menu bar along with a menu of options for the user to choose from.

The first step to creating a menu bar app is to create a new macOS project Cocoa Application project where the “Use Storyboards” checkbox is clear. This will create a project that contains pull-down menus and a single window represented by a .xib file.

First, you can delete the .xib file or hide it. To hide the .xib window, click on it and choose View > Utilities > Show Attributes Inspector. Now clear the “Visible At Launch” check box. This keeps the window from appearing but still keeps it in your project in case you need it for any reason.

Once you’ve deleted or hidden the .xib window, the next step is to make sure the pull-down menus and program icon don’t appear on the Dock. To do this, click the Info.plist file in the Navigator pane to display a long list of various options.

Click on the last option and a + and – sign icon appears. Click this + icon to create a new line. In this new line, choose “Application is agent (UIElement)”.

Make sure the Type for this line is Boolean and its Value is YES. This option will keep the program’s icon from appearing on the Dock when running and keep its pull-down menus from appearing on the left side of the menu bar at the top of the screen.

Once you’ve hidden the window, pull-down menus, and Dock icon, the last step is to write Swift code to create the menu bar title and a pull-down menu.

Open the AppDelegate.swift file and underneath the class AppDelegate line, add the following:

var item : NSStatusItem? = nil

This creates the object that will appear on the status bar. Inside the applicationDidFinishLaunching function, you need to assign this “item” object an actual value:

item = NSStatusBar.system().statusItem(withLength: NSVariableStatusItemLength)

The above code creates an object, but we still need to display it on the menu bar. One way to display the menu bar is as an icon (which will be covered in a future blog post). A second way is as text, which you can create by defining its title property like this:

item?.title = "MyMenu"

The string assigned to the title property can be anything you want, but keep it short and descriptive.

After you’ve created a menu title, the next step is to create a pull-down menu list. To do this, you need to create an NSMenu object and then fill it with titles like this:

let menu = NSMenu()
menu.addItem(NSMenuItem(title: "Option 1", action: #selector(AppDelegate.testMe), keyEquivalent: ""))
menu.addItem(NSMenuItem(title: "Quit", action: #selector(AppDelegate.quitMe), keyEquivalent: ""))
item?.menu = menu

To define each item in the pull-down menu, you need to use the addItem command. The title property defines the command that appears on the menu and the #selector identifies the function that runs when the user clicks on that menu item.

The keyEquivalent property lets you define a letter that represents a shortcut keystroke for accessing the command. In general, it’s best to leave it blank because it takes more time to use the keystroke shortcut than it will to simply click on the menu item they want.

Finally, you need to assign your NSMenu object to your menu bar’s menu property.

At this point, your pull-down menus will appear but won’t do anything because you still need to write functions that run when the user clicks on a particular menu item.

In the above example, the two #selector commands are looking for a testMe and a quitMe function (although you can choose any name you wish). So if you used the above code, the two functions you’d need to create are as follows:

    func testMe() {
        print ("It works!")
    }
    
    func quitMe() {
        NSApplication.shared().terminate(self)
    }

The NSApplication.shared().terminate(self) command simply quits the program.

The complete code of the AppDelegate.swift file should look like this:

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet weak var window: NSWindow!

    var item : NSStatusItem? = nil
    
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        // Insert code here to initialize your application
        
        item = NSStatusBar.system().statusItem(withLength: NSVariableStatusItemLength)
        
        //Displays text on menu bar
        item?.title = "TestMe"
        
        // Defines function to run when the user clicks on the text on menu bar
        //item?.action = #selector(AppDelegate.testMe)
        
        let menu = NSMenu()
        menu.addItem(NSMenuItem(title: "Option 1", action: #selector(AppDelegate.testMe), keyEquivalent: ""))
        menu.addItem(NSMenuItem(title: "Quit", action: #selector(AppDelegate.quitMe), keyEquivalent: ""))
        item?.menu = menu
    }
    
    func testMe() {
        print ("It works!")
    }
    
    func quitMe() {
        NSApplication.shared().terminate(self)
    }

    func applicationWillTerminate(_ aNotification: Notification) {
        // Insert code here to tear down your application
    }


}

If you choose Product > Run, you should see the menu text “TestMe” appear on the menu bar. If you click on it, a pull-down menu appears displaying “Option 1” and “Quit”. If you click Option 1, the program prints “It works!” in the Debug area of the Xcode window. If you click Quit, your program stops running.

This simple project demonstrates how to create a simple menu bar app that displays a menu title (“TestMe”) on the menu bar. When the user clicks on this menu title, a pull-down menu appears with two options.

You can download the complete MenuBarApp project here.
January 10th, 2017 by
HTML Snippets Powered By : XYZScripts.com