How to Use NSTouchBar on macOS

Learn how to use the new NSTouchBar APIs to add Touch Bar support for your macOS apps. By Andy Pereira.

Leave a rating/review
Save for later
Share

After years of waiting and rumors, Apple finally released a set of new MacBook Pros. One of the new exciting things announced was the inclusion of a touch screen. Well… sort of.

The new Touch Bar replaces the traditional function keys found on all MacBooks in the past for a dynamic, multi-touch screen. And the best part is it’s fully open to developers, so you can use it to offer new ways to interact with your macOS applications.

If you’re a macOS developer, you’ll want to take full advantage of this new technology right away. In this tutorial, I’ll show you how you can use the new NSTouchBar API to easily create a dynamic touch bar for your macOS app.

Note: This tutorial requires Xcode version 8.1 or later. You will also need to ensure that you have macOS 10.12.1, build 16B2657 installed on your computer first. If you do not have this version, you will not be able to show the Touch Bar Simulator. To check, go to  > About This Mac, and click where you see 10.12.1. This will then show your build number.

About Mac

If you do not see 16B2657, you can download the update from Apple.

What is the Touch Bar?

As mentioned, the Touch Bar is a small touch screen that allows users to interact with apps (and their computer) in a whole new way.

Screen Shot 2016-10-31 at 12.44.31 PM

There are three default sections on the Touch Bar:

  • System Button: Depending on context, this will show a system level button, like Esc.
  • App Region: The default area provided for your app to show items.
  • Control Strip: This is a replacement of your familiar keys that you’d use to control screen brightness, volume, or music playback.

As with every new technology from Apple, there are a set of Human Interface Guidelines that you should follow when working with the Touch Bar. You should familiarize yourself with them here, as they are very important to maintaining a consistent pattern to your users.

Very briefly, here are a few sections of the guide that really stand out:

  • Don’t expose functionality just in the Touch Bar: This isn’t the place to keep things secret from users that haven’t upgraded their hardware yet. If you’re going to put it in the Touch Bar, make sure you can perform the action somewhere else in your app. Apple says that the Touch Bar can even be disabled, so don’t count on your users to always see it.
  • The Touch Pad is an extension of the Keyboard and Trackpad, not a display: Yes, it’s a screen, but it’s not a secondary display. Don’t distract the user with scrolling content or alerts.
  • Respond Immediately: When users tap a key on the keyboard, they expect immediate results. Similarly, when someone taps a virtual button on the touch bar, they also expect immediate results.

How Do I Support the Touch Bar?

To add support for the TouchBar in your apps, you use some new classes provided by Apple: NSTouchBar and NSTouchBarItem (and its subclasses).

Some of the NSTouchBarItem subclasses include features like:

  • Slider: Adjusts a value
  • Popover: Hide more functionality behind another item.
  • Color Picker: Pretty much says it all (a color picker if you didn’t catch it ;] ).
  • Custom: This is probably going to be your go-to item for a lot of things. It allows you to add simple labels, buttons, and all sorts of other controls.

You can customize your items quite a bit. From text size and color, to images, you can offer your users a modern approach to the keyboard that hasn’t been available before. Just remember the guidelines, and you should be good to go.

Getting Started

You’re probably ready to get started! To follow along, download this sample project here.

The application is a very simple Travel Log, that only does what is needed for the purposes of our tutorial. With the project open, go to Window > Show Touch Bar. You’ll now see the Touch Bar Simulator on your screen.

Initial Bar

Build and run the app, you’ll notice the Touch Bar is empty, aside from the System Button and Control Strip.

Starter App

First Bar

Before you can add anything to the Touch Bar, you’ll need to tell the system your application can customize the Touch Bar. Open AppDelegate.swift, and paste the following into applicationDidFinishLaunching(_:):

func applicationDidFinishLaunching(_ aNotification: Notification) {
  if #available(OSX 10.12.1, *) {
    NSApplication.shared().isAutomaticCustomizeTouchBarMenuItemEnabled = true
  }
}

This takes care of all the necessary validations and activation of your Touch Bar menu items for you. At the time of this writing the current version of Xcode does not have macOS 10.12.1 available as a deployment target, so you will need to place #available(OS X 10.12.1, *) around code or extensions dealing with the Touch Bar. Luckily, Xcode will give you a friendly error if you forget ;]

Open WindowController.swift, and look at makeTouchBar(). This method is checking if ViewController has a Touch Bar that can be returned. If so, it will send that Touch Bar to the Window, and be presented to the user. Right now, there is no Touch Bar being created, so nothing is shown.

Before you can go making your own touch bars, and touch bar items, you need to be aware that instances of these classes all require unique identifiers. Open TouchBarIdentifiers.swift to see how these have been created for this project. There are extensions for both NSTouchBarCustomizationIdentifier, and NSTouchBarItemIdentifier.

Go to ViewController.swift, and add the following at the end of the file, where the TouchBar Delegate is marked:

@available(OSX 10.12.1, *)
extension ViewController: NSTouchBarDelegate {
  override func makeTouchBar() -> NSTouchBar? {
    // 1
    let touchBar = NSTouchBar()
    touchBar.delegate = self
    // 2
    touchBar.customizationIdentifier = .travelBar
    // 3
    touchBar.defaultItemIdentifiers = [.infoLabelItem]
    // 4
    touchBar.customizationAllowedItemIdentifiers = [.infoLabelItem]
    return touchBar
  }
}

Here, you override makeTouchBar(), which is required for your view or window to create a touch bar. You also did the following:

  1. Create a new TouchBar and set the delegate.
  2. Set the customizationIdentifier. Remember, every TouchBar and TouchBarItem need to have unique identifiers.
  3. Set the Touch Bar’s default item identifiers. This tells the Touch Bar what items it will contain.
  4. Here, you set what order the items should be presented to the user.

You’re still not quite ready to see anything in your Touch Bar yet. You’ll need to tell the Touch Bar what the .infoLabelItem should look like. In the same extension, add the following:

func touchBar(_ touchBar: NSTouchBar, makeItemForIdentifier identifier: NSTouchBarItemIdentifier) -> NSTouchBarItem? {
    switch identifier {
    case NSTouchBarItemIdentifier.infoLabelItem:
      let customViewItem = NSCustomTouchBarItem(identifier: identifier)
      customViewItem.view = NSTextField(labelWithString: "\u{1F30E} \u{1F4D3}")
      return customViewItem
    default:
      return nil
    }
}

By implementing touchBar(_:makeItemForIdentifier:), you can customize your touch bar items anyway you’d like. Here, you’ve created a simple NSCustomTouchBarItem, and set its view to an NSTextField. Build and run your application, and you’ll now see the Touch Bar has a new item.

TouchBar FirstItem

Yay! You got a… label. That’s not super helpful, though. It’s time to add some controls.

touchbar_ragecomic