Playing a Single-Tap Haptic Pattern

Create and play a transient haptic pattern from a dictionary literal inline.


This article describes how to define the haptic pattern for a single haptic tap and how to play that haptic pattern through a haptic engine.

Create a Haptic Engine

The CHHapticEngine is your app’s interface to the haptic device. An instance of a haptic engine allows you to create a CHHapticPatternPlayer or CHHapticAdvancedPatternPlayer to play individual haptics. Create the haptic engine as described in Preparing Your App to Play Haptics.

Specify a Dictionary Literal

The next step is to create a dictionary literal representing the haptic. The following literal represents a single haptic tap:

NSDictionary* hapticDict =
           @[ // Start of array
             @{  // Start of first dictionary entry in the array
                 CHHapticPatternKeyEvent: @{ // Start of first item
                         },  // End of first item
               }, // End of first dictionary entry in the array
            ], // End of array
     }; // End of haptic dictionary

Each entry in the dictionary shown above is a haptic event, with an event type, a start time, and a duration. In this case, the event type is CHHapticEventTypeHapticTransient because a single tap is a transient pattern—a quick impulse. The time is CHHapticTimeImmediate to indicate that the event begins immediately, right after time 0. The duration of 1.0 indicates that the event will last a second.

Create a Haptic Pattern Player from the Dictionary

Initialize a CHHapticPattern from the dictionary you just created.

NSError* error;
CHHapticPattern* pattern = [[CHHapticPattern alloc] initWithDictionary:hapticDict error:&error];

When you’re ready to play your haptic, create a player to play that pattern. Each player is responsible for playing one pattern. You can reuse a player to play its pattern as many times as you'd like.

Use one of the haptic engine's factory methods, like createPlayerWithPattern:error:, to create the haptic pattern player.

NSError* error = nil;
id<CHHapticPatternPlayer> player = [_engine makePlayerWithPattern:pattern error:&error];

If you call startAtTime:error: on a player that's already playing, it restarts itself at the beginning of the pattern.

Creating players is inexpensive. They're lightweight objects, so create and discard them freely. Unless your app requires real-time, latency-free haptic feedback in response to user interaction—like precise ticks on a dial—you can create your player right before playing the haptic.

Start the Engine and Play the Haptic Pattern

Start the haptic engine before playing a haptic player, and stop the engine once you've finished playing all haptic patterns. Play the haptic by calling the player’s startAtTime:error: method, specifying a start time and duration.

[_engine startWithCompletionHandler:^(NSError* returnedError) {
    NSLog(@"--- The haptic engine started. ---");
[player startAtTime:0 error:&error];
[_engine stopWithCompletionHandler:^(NSError* _Nullable error) {
    NSLog(@"--- The haptic engine stopped. ---");

If the engine is running when you call startAndReturnError:, the system plays the haptic at the scheduled time. Playback follows a “fire & forget” model: Your app doesn’t need to keep the player and pattern in memory once you’ve called startAndReturnError:. Make sure you retain your engine so it doesn’t exit scope during your program.

Unless you're playing several haptic patterns in succession, bookend haptic playback with starting and stopping the engine. Starting the engine ensures that the haptic engine is running when you schedule a haptic to be played. Stopping the engine after you finish playing the haptic conserves power and allows it to prepare for the next time your app needs haptic playback. Be aware that your engine may stop on its own in auto-shutdown mode.

See Also


Preparing Your App to Play Haptics

Set up your app to play haptics.


An object that manages your app's requests to play haptic patterns.


An object representing a haptic waveform.