PyObjC CoreHaptics Framework

12.1 · active · verified Tue Apr 14

This library provides Python bindings for Apple's CoreHaptics framework on macOS, allowing developers to integrate sophisticated haptic feedback into their applications. As part of the larger PyObjC bridge, it enables direct interaction with Objective-C APIs from Python. The current version is 12.1, and releases generally follow macOS SDK updates and Python version support changes.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to initialize the `CHHapticEngine`, define a simple haptic impact using `CHHapticEvent` and `CHHapticEventParameter`, create a `CHHapticPattern`, and play it. This code will only run on macOS systems with haptic feedback capabilities. Ensure your system's haptic settings are enabled.

import objc
from CoreHaptics import (
    CHHapticEngine, CHHapticPattern, CHHapticEvent,
    CHHapticEventParameter, CHHapticEventParameterID, CHHapticEventType
)
from Foundation import NSArray, NSThread

def play_haptic_feedback():
    """
    Initializes a CHHapticEngine and plays a simple haptic impact.
    Requires macOS and haptic feedback enabled.
    """
    print("Attempting to play haptic feedback...")

    # Create an error holder (PyObjC will populate if an error occurs)
    error = objc.nil

    # 1. Initialize the haptic engine
    engine = CHHapticEngine.alloc().initAndReturnError_(objc.ptr(error))
    if engine is None:
        print(f"Error initializing CHHapticEngine: {error[0] if error else 'Unknown error'}")
        return

    # 2. Set an error handler for the engine
    engine.setErrorHandler_(lambda err: print(f"CHHapticEngine encountered an error: {err}"))

    # 3. Start the engine
    success, error = engine.startAndReturnError_(objc.ptr(error))
    if not success:
        print(f"Error starting CHHapticEngine: {error[0] if error else 'Unknown error'}")
        return
    print("CHHapticEngine started.")

    # 4. Create haptic event parameters
    intensity_param = CHHapticEventParameter.alloc().initWithParameterID_value_(
        CHHapticEventParameterID.CHHapticEventParameterIDHapticIntensity, 0.8
    )
    sharpness_param = CHHapticEventParameter.alloc().initWithParameterID_value_(
        CHHapticEventParameterID.CHHapticEventParameterIDHapticSharpness, 0.6
    )

    # 5. Create a haptic event (a transient impact)
    event = CHHapticEvent.alloc().initWithEventType_parameters_relativeTime_duration_(
        CHHapticEventType.CHHapticEventTypeHapticTransient,
        NSArray.arrayWithArray_([intensity_param, sharpness_param]),
        0.0,
        0.1
    )

    # 6. Create a haptic pattern from the event
    pattern = CHHapticPattern.alloc().initWithEvents_parameters_error_(
        NSArray.arrayWithArray_([event]),
        objc.nil,
        objc.ptr(error)
    )
    if pattern is None:
        print(f"Error creating CHHapticPattern: {error[0] if error else 'Unknown error'}")
        engine.stopWithCompletionHandler_(objc.nil)
        return

    # 7. Create a player for the pattern
    player, error = engine.createPlayerWithPattern_error_(pattern, objc.ptr(error))
    if player is None:
        print(f"Error creating CHHapticPatternPlayer: {error[0] if error else 'Unknown error'}")
        engine.stopWithCompletionHandler_(objc.nil)
        return

    # 8. Start the player
    success, error = player.startAtTime_error_(0, objc.ptr(error))
    if not success:
        print(f"Error starting CHHapticPatternPlayer: {error[0] if error else 'Unknown error'}")
        engine.stopWithCompletionHandler_(objc.nil)
        return
    print("Haptic pattern started playing.")

    # 9. Keep the script alive long enough for the haptic to play
    NSThread.sleepForTimeInterval_(1.5)

    # 10. Stop the engine gracefully
    success, error = engine.stopAndReturnError_(objc.ptr(error))
    if not success:
        print(f"Error stopping CHHapticEngine: {error[0] if error else 'Unknown error'}")
    print("CHHapticEngine stopped.")

if __name__ == "__main__":
    play_haptic_feedback()

view raw JSON →