macOS Native Client Applications


The UPDDMultitouch framework allows adding multi-touch support to macOS AppKit and SwiftUI applications. It attempts to make the process as simple as possible by allowing any NSView or NSView-derived class that implements the UPDDMultitouchView protocol to receive multi-touch events in a similar manner as iOS.

The UPDDMultitouch framework can be downloaded from here: upddmultitouch-framework.zip

The source code for the framework along with a basic multi-touch slider demo implemented using both AppKit and SwiftUI can be found here: upddmultitouch-framework-and-demo-src.zip

To use the framework, add it to your Xcode project, and then in the "Build Phases" settings for your application target, create a new "Copy Files" phase and set it up to copy UPDDMultitouch.framework into your application's Frameworks directory:


You can now import UPDDMultitouch in your source files. You must call UPDDMultitouch.initialize() when the application starts up, and UPDDMultitouch.deinitialize() when the application shuts down. We recommend calling these functions in your application delegate's applicationDidFinishLaunching and applicationWillTerminate methods.

You can then create a subclass of NSView or any NSView-derived class that implements the UPDDMultitouchView protocol in order to receive touch events. Touch events will be delegated to any view that implements this protocol automatically. This protocol requires three methods:
upddTouchesBegan, upddTouchesMoved, and upddTouchesEnded.

Each method has a single parameter, a set of UPDDTouch objects:
In Objective-C:
NSSet<UPDDTouch *> *
In Swift: Set<UPDDTouch>

UPDDTouch is designed to provide a similar interface as UITouch in iOS. It has the following properties:

deviceIdentifier: int
Returns the unique ID of the touch device that produced the touch.

identifier: int
The identifier for the touch. A single touch from the moment contact begins to when it ends will have the same identifier. The identifier is device-dependent, and the same value may be reused for subsequent touches. Simultaneous touches will always have a different identifier.

phase: NSTouchPhase
An enum indictating the life-cycle of the touch. Possible values are: NSTouchPhaseBegan, NSTouchPhaseMoved, NSTouchPhaseStationary, and NSTouchPhaseEnded.

screenPosition: NSPoint
The position of the touch, in global coordinates

previousScreenPosition: NSPoint
The position of the touch for the previous cycle, in global coordinates

normalizedPosition: NSPoint
The position of the touch, in normalized coordinates, where (0,0)=the top-left corner of the screen, and (1,1)=the bottom-right corner of the screen

previousNormalizedPosition: NSPoint
The position of the touch for the previous cycle, in normalized coordinates.

timestamp: double
A timestamp for the touch, in seconds, relative to the system startup time.

pressure: int
The raw pressure value of the touch. The range of this value is device dependent, and only supported available with pressure-enabled touch devices

pressureEnabled: bool
True when the touch comes from a pressure-enabled device

view: NSView
The view the touch has been dispatched to

UPDDTouch also has two methods:

func locationInView(view: NSView) -> NSPoint
Returns the position of the touch, in the local coordinates of the given view.

func previousLocationInView(view: NSView) -> NSPoint
Returns the position of the touch during the previous cycle, in the local coordinates of the given view.

For applications built using SwiftUI:

To add a touch-enabled view to a SwiftUI application, create a custom view implementing the UPDDMultitouchView protocol as you would with an AppKit application, and then add it into your SwiftUI content hierarchy using NSViewRepresentable. The SliderDemoSwiftUI project linked above demonstrates how to do this.