2

Is there any API to check whether the running machine has a touch bar (or Xcode's touch bar simulator)?

I have some methods to be invoked only if a touch bar exists. If I just check the nullability of touchBar property of a responder, it automatically creates a touchBar instance even if the machine doesn't support it. But I don't want to create one when it doesn't make sense.

1024jp
  • 2,058
  • 1
  • 16
  • 25

3 Answers3

6

From Apple's NSTouchBar reference:

There is no need, and no API, for your app to know whether or not there is a Touch Bar available. Whether your app is running on a machine that supports the Touch Bar or not, your app’s onscreen user interface (UI) appears and behaves the same way.

So clearly Apple's view is the touch bar is additional UI which replicates functionality available elsewhere and as such your app doesn't need to know whether it is present or not.

So the answer to your question is there is no public API intended for this purpose.

(I suspect you can figure it out - consider the delegates called, events generated, etc. - without calling any private UI or relying on machine ID's, but I don't know you can.)

HTH

CRD
  • 52,522
  • 5
  • 70
  • 86
  • 1
    Aha, add a flag in delegate calling or `makeTouchBar()` is a good idea. And I missed Apple mentioned about it in the reference. Thanks. – 1024jp Dec 01 '16 at 17:30
  • ..unfortunately it *can* be useful, at least for debugging purposes, as the presence of a Touch Bar triggers specific behavior in App Kit that can cause very specific bugs and crashes if not handled properly (ask me how I know..) – Jay Feb 18 '21 at 17:18
1

replicates functionality available elsewhere

This seems remarkably silly on Apple's part. Say you have an audio/video app that has a scrubber bar functionality for something. Without a touch bar, the control is in the main window on the screen. With a touch bar, it's there. So, does this mean that Apple wants such an app to have such a control in both places at the same time?

The only "downside" I can see for them allowing an app to do such a functionality is that it makes it hard(er) for someone with a Touchbar mac to explain how to use said app to someone else who doesn't have a Touchbar (or vice versa).

I can see that (maybe) they don't want apps to necessarily have features that are only available on the Touchbar and not available any other way. But this strikes me a bit like saying to a developer of an iPhone/iPad app that an app doesn't need to know which device it's running on. That's the whole reason they added Adaptive Layouts and Traits, right? Isn't "Touchbar/No-Touchbar" the same thing?

It could be that this is one of those things that is right at the top of their "Touchbar API 2.0 list" - but they know that if they allow it now, it will likely be misused by someone. (Someone makes an app that behaves radically differently with and without a Bar, and so it either becomes a mess to try to explain and/or figure out, or the TB functionality becomes a kind of "neglected stepchild interface" rather than something that is well-thought out.)

Jim Witte
  • 19
  • 1
  • 6
  • I use my MBP with touchbar with an external keyboard, mouse, and monitor connected. The touchbar is a long way away from where my hands are, and in the normal course of events I don't use it. I would find it annoying if an app hid on-screen controls that were normally available, just because my MBP does technically have a touchbar. I imagine Apple has this sort of scenario in mind. – bhaller Jan 06 '17 at 23:25
-1

This function checks if the system is a MacBook Pro with TouchBar ("MacBookPro13,2" & "MacBookPro13,3"). If Apple releases other devices with Touch Bar in the future you have to update the function.

func touchbarAvailable() -> Bool {
    var size = 0
    sysctlbyname("hw.model", nil, &size, nil, 0)
    var machine = [CChar](repeating: 0,  count: Int(size))
    sysctlbyname("hw.model", &machine, &size, nil, 0)

    if (String(cString: machine) == "MacBookPro13,2" || String(cString: machine) == "MacBookPro13,3") {
        return true
    }
    return false
}
Flocked
  • 1,898
  • 2
  • 36
  • 57