all micro contact rss

Touch Bar Support and Interface Builder

One of the many challenges I faced while building x2y for Mac was getting touch bar support working. This is a very new feature, available only on the latest MacBook Pro machines, which are barely now just starting to ship. Nevertheless, I wanted my new app to support this new hardware right out of the gate.

As is the case with most new APIs, finding documentation and examples for NSTouchBar wasn’t as easy as it would have been for something that has been around much longer. There is a nice write up on Ray Wenderlich, of course, but it involved doing all the touch bar creation in code. I greatly prefer using Interface Builder whenever possible.

I could see clearly that Interface Builder objects existed for touch bar items. Xcode 8.1 has touch bars, spacers, buttons, popovers, color pickers, etc., ready to be dragged and dropped right into your storyboards. They wouldn’t exist if you couldn’t use them. But how? I couldn’t find any good write-ups on what to do once you’ve dragged them into the storyboard. Unlike view controllers, touch bars don’t get storyboard IDs, so there doesn’t seem to be any way to refer to an IB touch bar in code. How was I going to get a touch bar to show up, without ignoring these Interface Builder built-in tools and rolling the entire thing in code?

Determined to not do it the long way, I kept poking around until I finally stumbled across this video from Nick Walter on YouTube. In it, he shows that all you need to do is drag a touch bar item to your window controller, throw on the items you want, and it should automatically show up for that window. Wire the buttons to your first responder actions, and you’re good to go. Super easy.

But I had done that, to no avail. When I tried this in x2y, it wasn’t working. What was I missing? All I could see whenever I launched the app was the standard blank touch bar, with the lone keyboard popover button to show typing suggestions.

Typing suggestions. Wait a minute. My app basically always has an active NSTextField in focus. And NSTextField is one of those classes that gets “Automatic” support for standard touch bar typing suggestions. In other words, any NSTextField you put in your app will replace your custom touch bar with the standard typing suggestions bar. So my app was always overriding my custom touch bar from Interface Builder.

I needed a way to get my NSTextFields not to do that. Auto-correct and text suggestions make no sense in x2y, anyway, since you can only type numbers into the fields. So I didn’t mind losing the typing suggestions functionality.

A little more research, and I found the way to override the standard touch bar behavior for NSTextField: add an extension to NSTextView.

Why NSTextView? If you’re unfamiliar with macOS development, it’s important to know that NSTextFields themselves never become the First Responder in AppKit. Instead, when you click on a text field anywhere on the Mac, a hidden NSTextView called the field editor is what actually gets first responder status. So I needed to override NSTextView, not NSTextField, to get the standard touch bar to stop showing up.

Here’s the code I placed into my NSTextView extension file.

extension NSTextView {

     @available(OSX 10.12.1, *)
     override open func makeTouchBar() -> NSTouchBar? {

          let touchBar = super.makeTouchBar()
          touchBar?.delegate = self

          return touchBar
     }
}

Notice the @available ensures that this only runs on a Mac running 10.12.1, thus not crashing earlier versions of the OS that know nothing of touch bars.

I call super.makeTouchBar() to get the touch bar from my main window, as opposed to the standard text view bar. Simple enough.

Once I placed this into my app, my custom touch bar from Interface Builder stopped being overridden.

I know there are always times and situations where doing things directly in code makes more sense than Interface Builder. But for something as simple as adding a few buttons to a touch bar, it seems like a lot of extra steps to write it all out by hand, rather than dropping the objects into Interface Builder. Take a look at the tutorial from Ray Wenderlich, and see for yourself how much more work it is to accomplish a simple bar with a few buttons on it in code.

Luckily, Apple gives us the option to do things either way, even in the early days of a new class like NSTouchBar. The more I investigate this API, the more I’m convinced that touch bars were no afterthought on Apple’s part, but rather something that Apple carefully considered, not just from a hardware standpoint, but in software as well. I’m excited to see what new capabilities the touch bar gets over time.

x2y for Mac

x2y for iOS was my first app, and I’ve always been particularly proud of it. It’s come a long way in its four major iOS versions, but I hadn’t added very much to it this year. I had one small customer request (the stepper tool), but that was about all I could think to add at this point. It’s a simple tool that does its job very well. I didn’t want to tack on a bunch of extra features that no one wanted.

So I thought, rather than trying to justify some major new iOS version, the next logical move for this app would be to finally make the macOS version.

Perhaps some other iOS developers can relate to this, but simply adding a line item “Mac Version” in your task manager is not the best way to get a Mac app made. That item has been sitting in my OmniFocus for more than two years, intimidating me with the sheer scope of what it appeared to involve. It was far too easy to brush it off as something I’d have to do later, when I had more time to tackle some serious new learning.

I had done some Mac design in the past, and I’ve been using a Mac as long as I’ve been using computers, but I had never actually coded a Mac app before. I knew AppKit was going to be a challenge compared to UIKit.

But here’s the thing; the transition over to AppKit was not that bad. Consider this: I’m primarily a designer and only a part-time self-taught coder. I had very limited knowledge of Swift going into this project, having only worked with it in my two sticker pack apps. Yet I managed to build x2y for Mac, in Swift, in ten days. If I can do that, any experienced iOS developer can certainly become competent on the Mac pretty quickly.

x2y now has a spot in my Dock, and it has already proven very useful for me to be able to do aspect calculations while coding web sites, never having to change to another device or even move my hands from the keyboard of my laptop.

If you want to check out x2y for Mac, it’s available now on the Mac App Store.

If you’ve been afraid of the Mac in the past; if you’ve had a “Mac version” line item or two sitting in your task manager for a few years now, like I did; if you have this great app idea that just doesn’t make sense for iOS but would be perfect for the Mac, you should consider going for it. It’s not going to be as hard as you think. And there can never be enough great software for macOS.

Full Screen is a Preference

Apple sells far more laptops than desktops these days. And the majority of those laptops have screens that are 13 inches or smaller.

When you use a smaller-screened laptop as your primary machine, you learn quickly that full-screen apps are actually quite useful on a Mac with a smaller screen. There are obviously some apps, particularly utilities, that I run as windowed apps, but I’d say the majority of my apps are running full screen most of the time now.

Which is why I get so frustrated that so few Mac apps remember my preference to be running in full screen.

Every time I relaunch these apps, I need to wait for the window to load, then click on the full-screen button to get it back to full-screen mode. It’s a small thing, but add it up over time with most of my apps every time I launch or reboot, and it becomes annoying quickly.

At first, I wasn’t sure it was even possible for developers to have an app launch in full screen. But then I realized Apple’s own Mail.app manages to remember my full-screen preference between launches just fine.

Maybe they are using a private API to do this? I wondered. So I started looking for third-party apps that remembered my full-screen preference. Sure enough, a few of them do it. (One of those apps, Ulysses, I’m using to write this, in fact.)

It’s clearly possible. Why do so few of my third-party apps do it, then? Maybe it’s really hard.

So I fired up Xcode (where I was working on my own Mac app x2y anyway). A little research, a few lines of code to save a user default on windowWillEnterFullScreen and windowWillExitFullScreen, and sure enough, x2y was remembering my full-screen preference between launches. Check the pref on launch and toggle full screen if needed. Took me all of five minutes.

So what’s going on here? My guess is most Mac devs don’t use full screen apps very often. They are using large monitors or multiple monitors for Xcode, and while they might test their apps in full screen, they don’t think to save the full screen preference between launches, because they don’t use apps that way themselves.

The isRestorable property in macOS conveniently saves window position between launches without much effort for developers. Unfortunately, isRestorable doesn’t have any knowledge of whether the app is in full-screen mode. It would be nice if Apple provided a simple checkbox for remembering full-screen status in IB somewhere.

Meanwhile, on behalf of Mac laptop users everywhere, allow me to plead with my Mac developer friends: When I put your app in full screen and keep it that way, I’m showing intent. And good developers always pay attention to a customer’s intent, and use it to anticipate their preferences. Consider taking a few minutes on your next version to implement saving a preference for running the app full screen. It’ll go a long way to making your customers happy.

Data, not Desire

INT. AN OFFICE BUILDING SOMEWHERE IN CUPERTINO. SITTING AT THE CONFERENCE TABLE ARE TIM COOK, PHIL SCHILLER, AND JONY IVE. THEY ARE BEGINNING TOP SECRET DISCUSSIONS ABOUT THE NEXT ITERATION OF MACBOOK PRO.

TIM: We have the latest data. Developers want a thicker laptop with the fastest processor possible. They’d rather have more battery life than a thinner profile. And for sure, it absolutely needs to max out at 32GB of RAM. Oh, and it should be upgradable, so they can buy a new one even less frequently than they already do.

PHIL: I talked to our engineers. All that is easily doable, but we’d have to make the thing a bit thicker.

JONY: I want thin.

TIM: Look, I know you guys have a vision for the future of the Mac, but the data just doesn’t show that your vision is what people want.

JONY: Thin.

TIM: Oh, come on…

PHIL: We have go thinner. He’s right. I hate carrying around a heavy notebook. Hey, how about we add a Touch Bar on top of the keyboard? That’ll be awesome!

TIM: But then we won’t have a physical escape key. That’ll be even worse for our all-important developer customer base! Our most important customers want thick and as fast as possible, damn it!

JONY: Thin.

TIM: Ok. Thin it is. Ship it.

All joking aside, I do worry, reading my Twitter timeline over the past few days, that some people actually believe Apple makes decisions based on what the executives personally want, rather than what data tells them is viable.

Unlike us, Apple has millions of dollars on the line in these decisions. If you think what executives at Apple want to build trumps what they think they can sell, you should take a moment and think about it more logically.

Here are a few things Apple knows that you don’t:

  • How many of each kind of laptop they’ve sold in the past five years
  • Where those purchasers live
  • What they do for a living
  • The detailed trend of PC sales worldwide across all PC types
  • What their customers’ general upgrade habits are
  • What they are likely to buy in the next year
  • How customers use their laptops
  • What kinds of places they use them
  • Which ports they use
  • What they’d like to do with their laptops that they can’t currently do
  • New technologies that aren’t ready for primetime yet, but will be coming in a few years
  • The long-term plan for the Mac software platform, as it continually evolves in response to worldwide trends
  • The limitations of what can and can’t be placed in a laptop due to physics, market forces, government regulations, availability of parts, etc.
  • The cost of manufacturing and transporting laptops worldwide, including component costs, long-term contracts, etc.

And about a gazillion other bits of data they’ve been collecting over several years of running the largest retail business on Earth.

Without access to any of this data, none of us is in a position to know what would be best for Apple.

It’s perfectly normal to be upset that the ideal laptop for you isn’t being made by Apple. But where you lose me is in assuming that decision is a mistake, or a purposeful snub, on Apple’s part.

Apple wants its products to succeed. And that’s as far as the want goes.

For all we know, Apple mocked up a more perfect laptop for developers, complete with Cherry switches on the keyboard and an oversized escape key. But then they analyzed the data, predicted the number of sales of such a beast, and decided it would lose money. So they opted not to make it.

Seems more likely to me than believing Tim Cook either doesn’t know what developers want, or that he doesn’t care because Apple is “obsessed with thin.”

These are not emotion-driven decisions. They are data-driven decisions.

Missing More than the Plot

“Anyone that watched the DJ scrubbing the Touch Bar and didn’t think it would be 100 times more natural to scratch with the on screen turn tables on a the flat Surface Studio screen wasn’t thinking too hard.”

(via John Kheit for the Mac Observer)

I basically disagree with this entire article. But that last bit really struck me as monumentally stupid.

If John knew any actual DJs, he’d know a few things:

  • Algoriddim already has an excellent iPad version of djayPro, which works great on the iPad’s touch surface. In fact, it won an Apple Design Award back in 2011.
  • Many pro DJs opt for a Mac over the iPad, despite the touch screen. The MacBook Pro is the industry standard for modern computer-based DJs.
  • No DJ wants to cart around a desktop machine the size of the Surface Studio into a night club for a gig. It would be ridiculously cumbersome.
  • From what everyone says about Surface Studio, the latency would probably outweigh the benefits of a larger touch surface

I’ve heard a number of people comment on how “stupid” the djay demo was. The point of the djay demo was to show the creative possibilities of what could be done with the Touch Bar. Try to see the potential, not the specifics. I thought it was a great demonstration of the versatility of the Touch Bar, if you are willing to put in a little effort and some creative thinking as a developer. This is way more than a row of keyboard shortcuts.

Who wants to wager with me that MacBook Pro sales outpace Microsoft Surface Studio sales by a million or more units in the next quarter? I think that’s a pretty safe bet, don’t you?