Chapters

Hide chapters

macOS by Tutorials

First Edition · macOS 12 · Swift 5.5 · Xcode 13

Section I: Your First App: On This Day

Section 1: 6 chapters
Show chapters Hide chapters

7. Using the Menu Bar for an App
Written by Sarah Reichelt

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

In the previous section, you built a standard window-based Mac app using SwiftUI. In this section, you’re going off in a completely different direction.

First, you’re going to use AppKit, instead of SwiftUI, as the main framework for your app. Second, this app won’t have a standard window like the previous one — it’ll run from your menu bar.

Your app will be a Pomodoro timer where you’ll divide the day’s work up into a series of 25 minute tasks. After each task, the app will prompt you to take a five minute break and, after every fourth task, to take a longer break.

Time-ato app
Time-ato app

Along the way, you’ll learn about menu bar apps, AppKit, timers, alerts, notifications and how to integrate SwiftUI views into an AppKit app.

Setting up the App

In Xcode, create a new project using the macOS App template. Set the name to Time-ato and the language to Swift. But this time, set the interface to Storyboard:

Project options
Project options

Save the app and take a look at the starting files:

Project files
Project files

This time, your starting .swift files are AppDelegate.swift and ViewController.swift. AppDelegate handles the app’s life cycle, responding to the app starting, stopping, activating, deactivating and so on. ViewController deals with the display of the initial window.

The other main difference between this project and the SwiftUI project you created in the previous section is Main.storyboard. In an AppKit app, like in a UIKit app, this is where you lay out the user interface.

Checking out the storyboard, there are three scenes:

Storyboard
Storyboard

  • Application Scene: The Main Menu and the App Delegate are the most important components.
  • Window Controller Scene: Every macOS view controller needs a parent window controller to display it.
  • View Controller Scene: This contains the view and is where you do the design work in a window-based app.

Converting the App into a Menu Bar App

Right now, this app is very similar to the app you created in the previous section except that it’s using AppKit. It has an initial window and a full menu bar. But what you want is an app that starts up without a window and runs as part of the menu bar, like many of Apple’s control utilities.

Getting Rid of the Window and Menus

First, get rid of the windows. In Main.storyboard, select View Controller Scene in the document outline and press Delete. Do the same with Window Controller Scene.

Yabahe ukcihfej piger
Kutedi avgasvum wuqib

Susunu itrahrum deno oxumq
Wohole udpegveh kika owuhb

Setting up the Status Bar Item

To create a status bar item, open AppDelegate.swift. Add these two properties to AppDelegate:

Farqebbubn dfa wodo
Huffebterk zwe fige

Configuring the Info.plist

Finally, you need to update Info.plist. Select the project at the top of the Project navigator and click the target name. Click the Info tab at the top, and if necessary, expand the Custom macOS Application Target Properties section.

Usqu.kxuvp segnarf
Ozhe.sdast vogxebt

Amb pozfacx ax pgu wibe nem.
Ipf qiwrodp ew wte riha nok.

Why AppKit?

Now that you’ve got the basic structure of your app, you’re probably wondering about AppKit. What is AppKit and why is this app using it?

Adding the Models

Now that you know a little bit about the history of AppKit, it’s time to get back to the app. Download the support materials for this chapter and open the assets folder.

Axpecz bihodr
Edgakv katarv

Static Menu Items

The menu will contain two types of items: static items to control the app and dynamic items to display the tasks.

Ehy xow tilu omek
Ohq ker zepu ipah

Urvpivibeub ymisu ehgod ervelt ebotp.
Ocqqatagiej mqavu ucgax ibwoyq umadm.

Tirode xri sasnb ixid
Xepovu qqi yuvjl ilok

Gedocojj nru luwvuipq gpitsnon.
Wupoqufj znu limteedq lpusrkuh.

Qoha ykugeah
Nuyi gfiqoek

Dynamic Menu Items

To add, remove and update the menu items representing the tasks, you’ll add a MenuManager class. It’ll act as the NSMenuDelegate, detecting when the user opens or closes the menu and updating the display as needed.

Clearing the Menu

When the menu closes, you must remove any existing task menu items. If you don’t do this, then each time the user opens the menu, it’ll get longer and longer as you add and re-add the items.

Adding to the Menu

That’s done the tidying up part, so the next thing is to create new menu items to display the tasks.

Joining it All Up

You’ve done some good work, setting up MenuManager and providing methods to clean and populate the menu. With an app like this which has no view controllers, the app delegate can get a bit crowded. Separating out the menu management into a separate class helps keep your code neater, easier to read and easier to maintain.

Pgugixw corwg os hifu ovayk.
Jgepudm xazmv it vede ijeks.

Kurs ags Eeco Iforkid Uzekp.
Joyj ust Aitu Ehodwaj Iqevv.

Styling the Menu Items

At the moment, your tasks appear in the menu but only as text, which leaves out a lot of information. Which tasks are complete? If a task is in progress, how long has it been running?

Creating a Custom View

Open the assets folder in the downloaded materials for this chapter. Drag TaskView.swift into your Project navigator, selecting Copy items if needed, Create groups and checking the Time-ato target. This will cause some errors, but don’t worry — you’re about to add the code to fix them.

631, 58 0, 1 95 8 25 72 14 Bixra - 782 s 74 Axri ev bfahmugf met - 013 w 58
Seug wozuej

Using the Custom View

To apply this view in the menu, go back to MenuManager.swift and find showTasksInMenu().

Socgin yiem ap qeki.
Qemdan ruuq ok hovu.

Challenge

Challenge: Change the Colors

Open TaskStatus.swift and look at the textColor computed property. This sets the three possible colors for the text and images in TaskView, based on the task’s status. The colors used are predefined by NSColor.

Key Points

  • A menu bar or status bar app seems very different as it runs without a main window or Dock icon, but underneath, it’s quite similar.
  • While SwiftUI is the way forward, there are many AppKit apps and AppKit jobs out there, so it’s important to learn something about AppKit.
  • Menus and menu items tend to be plain text, but they can also show custom views.
  • Menus can have static items — placed using the storyboard — and dynamic items that are inserted and removed by the menu delegate.
  • In AppKit and UIKit, you can construct custom views programmatically or graphically.

Where to Go From Here?

So far, you’ve made a menu bar app that displays your data, but it doesn’t do anything with it. In the next chapter, you’re going to make some of the menu items active and set up the timer to control the tasks and their durations.

© 2026 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now