
Corehaptics
- 225 installs
- 297 repo stars
- Updated August 4, 2026
- vabole/apple-skills
Add precise tactile feedback to iOS apps using Core Haptics patterns, CHHapticEngine lifecycle, custom AHAP patterns, and fallbacks when hardware or permissions limit haptics.
About
Teaches Core Haptics on Apple platforms: engine lifecycle, AHAP patterns, transient and continuous events, audio sync, and hardware fallbacks so agents add polished tactile feedback to SwiftUI and UIKit interactions.
- CHHapticEngine setup and recovery
- AHAP pattern authoring and playback
- Transient vs continuous haptic events
- Audio-haptic synchronization
- Capability checks and graceful degradation
Corehaptics by the numbers
- 225 all-time installs (skills.sh)
- +8 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #409 of 1,039 Mobile Development skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/vabole/apple-skills --skill corehapticsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 225 |
|---|---|
| repo stars | ★ 297 |
| Last updated | August 4, 2026 |
| Repository | vabole/apple-skills ↗ |
What it does
Add precise tactile feedback to iOS apps using Core Haptics patterns, CHHapticEngine lifecycle, custom AHAP patterns, and fallbacks when hardware or permissions limit haptics.
Files
Core Haptics Documentation
Search these docs to answer questions about haptic feedback APIs.
Return Format
Always include: 1. Summary - Answer the question concisely 2. File paths - List relevant files for full details
Files
corehaptics-index.md- Framework overview, patterns, eventschhapticengine.md- Haptic engine setup and playback
Navigation: Core Haptics
Class
CHHapticEngine
Available on: iOS 13.0+, iPadOS 13.0+, Mac Catalyst 13.0+, macOS 10.15+, tvOS 14.0+, visionOS 1.0+
An object that represents the connection to the haptic server.
class CHHapticEngineOverview
If you want your app to play custom haptics, you need to create a haptic engine. The haptic engine establishes the connection between your app and the underlying device hardware. Even though you can define a haptic pattern without an engine, you need the engine to play that pattern.

Even though your app makes a request through the haptic engine, the operating system could still override the request with system services, like haptics from system notifications.
Prepare Your App To Play Haptics
To prepare your app to play haptics, follow these steps, as demonstrated in the code below:
1. Create a haptic engine instance. Maintain a strong reference to it so it doesn’t go out of scope while the haptic is playing. 2. Call the haptic engine’s start(completionHandler:)) for an asynchronous start, or start()) to start the engine synchronously (immediately). 3. Stop the engine by calling stop(completionHandler:)) when your app finishes haptic playback.
Swift
do {
// 1. Create a haptic engine instance.
hapticEngine = try CHHapticEngine()
// 2. Start the haptic engine.
try hapticEngine.start()
} catch let error {
print("Engine Error: \(error)")
}
// 3. Stop the engine.
hapticEngine.stop(completionHandler: { (_) -> Void in
// Insert code to call after engine stops.
})Objective-C
// Create an error variable through which the engine returns error information.
NSError* error = nil;
// (1.) Create an instance of a haptic engine.
self.hapticEngine = [[CHHapticEngine alloc] initAndReturnError:&error];
// (2.) Start the haptic engine.
[self.hapticEngine startAndReturnError:&error];
// (3.) Stop the engine.
[self.hapticEngine stopWithCompletionHandler:^(NSError* error){
// Insert code to call after engine stops.
}];Although it’s possible to create content—CHHapticPattern instances—independent of a CHHapticEngine, your app must use an engine to play that content.
Inherits From
Conforms To
Initializing a Haptic Engine
- init()) Creates an instance of the haptic engine.
- init(audioSession:)) Creates a haptic engine from an audio session.
Starting and Stopping the Haptic Engine
- start()) Synchronously starts the haptic engine.
- start(completionHandler:)) Asynchronously starts the haptic engine.
- stop(completionHandler:)) Asynchronously stops the haptic engine and executes the completion handler once the engine has stopped.
- CHHapticEngine.CompletionHandler A typealias for a completion handler that the engine calls after starting or stopping.
Creating Haptic Pattern Players
- makePlayer(with:)) Creates a standard haptic pattern player from a haptic pattern.
- makeAdvancedPlayer(with:)) Creates an advanced haptic pattern player from a haptic pattern.
Modifying Playback Properties
- playsAudioOnly A Boolean value that indicates whether the engine ignores haptic events and plays audio events only.
- playsHapticsOnly A Boolean value that indicates whether the engine ignores audio events.
- isMutedForAudio A Boolean value that indicates whether the engine mutes audio.
- isMutedForHaptics A Boolean value that indicates whether the engine mutes haptics.
Playing a Pattern
- playPattern(from:)-6m9m5) Plays a pattern that’s defined in a file at the specified URL.
- playPattern(from:)-7u8se) Plays a pattern from the specified data.
Registering Audio Resources
- registerAudioResource(_:options:)) Registers an external audio to use as a custom waveform.
- unregisterAudioResource(_:)) Unregisters an external audio file that you previously registered with the engine.
- CHHapticAudioResourceID A type that identifies a custom audio resource.
Monitoring Finished Playback
- notifyWhenPlayersFinished(finishedHandler:)) Notifies you when all haptic pattern players have finished playing their haptic patterns.
- CHHapticEngine.FinishedHandler A type alias for a completion handler to execute after finishing haptic playback.
- CHHapticEngine.FinishedAction Possible actions to take after the haptic engine finishes execution.
Handling Haptic Engine Resets
- resetHandler A block that the haptic engine calls after recovering from a haptic server error.
- CHHapticEngine.ResetHandler A typealias for the block that the haptic engine calls after being reset.
Handling Haptic Engine Stoppages
- stoppedHandler A closure the haptic engine calls when it stops due to external causes.
- CHHapticEngine.StoppedHandler A typealias for the block that the haptic engine calls after it stops due to an external cause.
- CHHapticEngine.StoppedReason The enumeration of reasons the haptic engine stopped running.
Getting the Current Media Time
- currentTime The absolute time, in seconds, to use for scheduling haptic and audio events.
- CHHapticTimeImmediate A time constant used to schedule a command immediately.
Querying System Capabilities
- capabilitiesForHardware()) Returns a device capability object that describes the device’s haptic support and limitations.
- CHHapticDeviceCapability A protocol that defines haptics and audio capabilities of a device.
- CHHapticParameterAttributes A protocol for providing default, mininum, and maximum values of a parameter.
- attributes(forDynamicParameter:)) Requests the haptic device’s attributes for a dynamic parameter.
Managing Power
- isAutoShutdownEnabled A Boolean value that indicates whether the haptic engine starts and stops automatically on request from one of its pattern players, or when idle.
Initializers
Instance Properties
- intendedSpatialExperience The CHHapticEngine’s intended SpatialAudioExperience.
Essentials
- Preparing your app to play haptics Set up your app to play haptics.
- Playing a single-tap haptic pattern Create and play a transient haptic pattern from a dictionary literal inline.
- CHHapticPattern An object representing a haptic waveform.
- CHHapticPatternPlayer A protocol that defines a standard pattern player capable of playing haptic patterns with fixed parameters.
- CHHapticAdvancedPatternPlayer A protocol that defines an advanced pattern player capable of looping, seeking, pausing, and resuming haptic playback.
---
Extracted from Apple DocC JSON by apple-skills tooling. This is unofficial content. All documentation belongs to Apple Inc.
Navigation: Core Haptics
Essentials
Initializing a Haptic Engine
Starting and Stopping the Haptic Engine
- func start() throws)
- func start(completionHandler: (((any Error)?) -> Void)?))
- func stop(completionHandler: (((any Error)?) -> Void)?))
- CHHapticEngine.CompletionHandler
Creating Haptic Pattern Players
- func makePlayer(with: CHHapticPattern) throws -> any CHHapticPatternPlayer)
- func makeAdvancedPlayer(with: CHHapticPattern) throws -> any CHHapticAdvancedPatternPlayer)
Modifying Playback Properties
- var playsAudioOnly: Bool
- var playsHapticsOnly: Bool
- var isMutedForAudio: Bool
- var isMutedForHaptics: Bool
Playing a Pattern
Registering Audio Resources
- [func registerAudioResource(URL, options: [AnyHashable : Any]) throws -> CHHapticAudioResourceID](/documentation/corehaptics/chhapticengine/registeraudioresource(_:options:))
Audio Resource Keys
- let CHHapticAudioResourceKeyLoopEnabled: String
- let CHHapticAudioResourceKeyUseVolumeEnvelope: String
- CHHapticAudioResourceKey
Monitoring Finished Playback
- func notifyWhenPlayersFinished(finishedHandler: CHHapticEngine.FinishedHandler))
- CHHapticEngine.FinishedHandler
- CHHapticEngine.FinishedAction
Finished Actions
Initializers
Handling Haptic Engine Resets
Handling Haptic Engine Stoppages
- var stoppedHandler: CHHapticEngine.StoppedHandler
- CHHapticEngine.StoppedHandler
- CHHapticEngine.StoppedReason
Stopped Reasons
- case audioSessionInterrupt
- case applicationSuspended
- case engineDestroyed
- case gameControllerDisconnect
- case idleTimeout
- case notifyWhenFinished
- case systemError
Initializers
Getting the Current Media Time
Querying System Capabilities
Determining Support for Haptics
Determining Supported Parameters
- func attributes(forDynamicParameter: CHHapticDynamicParameter.ID) throws -> any CHHapticParameterAttributes)
- func attributes(forEventParameter: CHHapticEvent.ParameterID, eventType: CHHapticEvent.EventType) throws -> any CHHapticParameterAttributes)
Parameter Attributes
Managing Power
Initializers
Instance Properties
Creating a Haptic Pattern
- init(contentsOf: URL) throws)
- [init(events: [CHHapticEvent], parameterCurves: [CHHapticParameterCurve]) throws](/documentation/corehaptics/chhapticpattern/init(events:parametercurves:))
- [init(events: [CHHapticEvent], parameters: [CHHapticDynamicParameter]) throws](/documentation/corehaptics/chhapticpattern/init(events:parameters:))
- [init(dictionary: [CHHapticPattern.Key : Any]) throws](/documentation/corehaptics/chhapticpattern/init(dictionary:))
- CHHapticPattern.Key
Haptic Pattern Keys
- static let event: CHHapticPattern.Key
- static let eventDuration: CHHapticPattern.Key
- static let eventParameters: CHHapticPattern.Key
- static let eventType: CHHapticPattern.Key
- static let eventWaveformLoopEnabled: CHHapticPattern.Key
- static let eventWaveformPath: CHHapticPattern.Key
- static let eventWaveformUseVolumeEnvelope: CHHapticPattern.Key
- static let parameter: CHHapticPattern.Key
- static let parameterCurve: CHHapticPattern.Key
- static let parameterCurveControlPoints: CHHapticPattern.Key
- static let parameterID: CHHapticPattern.Key
- static let parameterValue: CHHapticPattern.Key
- static let pattern: CHHapticPattern.Key
- static let time: CHHapticPattern.Key
- static let version: CHHapticPattern.Key
Initializers
Retrieving Haptic Pattern Duration
Exporting a Haptic Pattern
- [func exportDictionary() throws -> [CHHapticPattern.Key : Any]](/documentation/corehaptics/chhapticpattern/exportdictionary())
Initializers
Starting and Stopping Playback
- func start(atTime: TimeInterval) throws)
- func stop(atTime: TimeInterval) throws)
- func cancel() throws)
Sending Parameters to a Haptic
- [func sendParameters([CHHapticDynamicParameter], atTime: TimeInterval) throws](/documentation/corehaptics/chhapticpatternplayer/sendparameters(_:attime:))
- func scheduleParameterCurve(CHHapticParameterCurve, atTime: TimeInterval) throws)
Silencing Haptic Playback
Setting Playback Properties
- var loopEnabled: Bool
- var loopEnd: TimeInterval
- var playbackRate: Float
- var completionHandler: CHHapticAdvancedPatternPlayerCompletionHandler
- CHHapticAdvancedPatternPlayerCompletionHandler
Controlling Playback
- func pause(atTime: TimeInterval) throws)
- func resume(atTime: TimeInterval) throws)
- func seek(toOffset: TimeInterval) throws)
Silencing Haptic Playback
Programmatic haptics
- Delivering Rich App Experiences with Haptics
- Playing Collision-Based Haptic Patterns
- Updating Continuous and Transient Haptic Parameters in Real Time
- CHHapticEvent
Categorizing Haptic Events
Specifying a Type
Enumerating Haptic Types
- static let audioContinuous: CHHapticEvent.EventType
- static let audioCustom: CHHapticEvent.EventType
- static let hapticTransient: CHHapticEvent.EventType
- static let hapticContinuous: CHHapticEvent.EventType
Creating Haptic Events
- [init(audioResourceID: CHHapticAudioResourceID, parameters: [CHHapticEventParameter], relativeTime: TimeInterval)](/documentation/corehaptics/chhapticevent/init(audioresourceid:parameters:relativetime:))
- [init(audioResourceID: CHHapticAudioResourceID, parameters: [CHHapticEventParameter], relativeTime: TimeInterval, duration: TimeInterval)](/documentation/corehaptics/chhapticevent/init(audioresourceid:parameters:relativetime:duration:))
- [init(eventType: CHHapticEvent.EventType, parameters: [CHHapticEventParameter], relativeTime: TimeInterval)](/documentation/corehaptics/chhapticevent/init(eventtype:parameters:relativetime:))
- [init(eventType: CHHapticEvent.EventType, parameters: [CHHapticEventParameter], relativeTime: TimeInterval, duration: TimeInterval)](/documentation/corehaptics/chhapticevent/init(eventtype:parameters:relativetime:duration:))
Configuring Haptic Events
- [var eventParameters: [CHHapticEventParameter]](/documentation/corehaptics/chhapticevent/eventparameters)
- CHHapticEvent.ParameterID
Haptic Event Parameter IDs
- static let hapticIntensity: CHHapticEvent.ParameterID
- static let hapticSharpness: CHHapticEvent.ParameterID
- static let attackTime: CHHapticEvent.ParameterID
- static let decayTime: CHHapticEvent.ParameterID
- static let releaseTime: CHHapticEvent.ParameterID
- static let sustained: CHHapticEvent.ParameterID
Audio Event Parameter IDs
- static let audioVolume: CHHapticEvent.ParameterID
- static let audioPan: CHHapticEvent.ParameterID
- static let audioPitch: CHHapticEvent.ParameterID
- static let audioBrightness: CHHapticEvent.ParameterID
Swift Initializers
Creating an Event Parameter
Haptic Event Parameter IDs
- static let hapticIntensity: CHHapticEvent.ParameterID
- static let hapticSharpness: CHHapticEvent.ParameterID
- static let attackTime: CHHapticEvent.ParameterID
- static let decayTime: CHHapticEvent.ParameterID
- static let releaseTime: CHHapticEvent.ParameterID
- static let sustained: CHHapticEvent.ParameterID
Audio Event Parameter IDs
- static let audioVolume: CHHapticEvent.ParameterID
- static let audioPan: CHHapticEvent.ParameterID
- static let audioPitch: CHHapticEvent.ParameterID
- static let audioBrightness: CHHapticEvent.ParameterID
Swift Initializers
Specifying an Event Parameter’s Value
Creating a Dynamic Parameter
- init(parameterID: CHHapticDynamicParameter.ID, value: Float, relativeTime: TimeInterval))
- CHHapticDynamicParameter.ID
Haptic Dynamic Parameter IDs
- static let hapticIntensityControl: CHHapticDynamicParameter.ID
- static let hapticSharpnessControl: CHHapticDynamicParameter.ID
- static let hapticAttackTimeControl: CHHapticDynamicParameter.ID
- static let hapticDecayTimeControl: CHHapticDynamicParameter.ID
- static let hapticReleaseTimeControl: CHHapticDynamicParameter.ID
Audio Dynamic Parameter IDs
- static let audioBrightnessControl: CHHapticDynamicParameter.ID
- static let audioVolumeControl: CHHapticDynamicParameter.ID
- static let audioPanControl: CHHapticDynamicParameter.ID
- static let audioPitchControl: CHHapticDynamicParameter.ID
- static let audioAttackTimeControl: CHHapticDynamicParameter.ID
- static let audioDecayTimeControl: CHHapticDynamicParameter.ID
- static let audioReleaseTimeControl: CHHapticDynamicParameter.ID
Swift Initializers
Specifying a Dynamic Parameter’s Value
Creating a Curve
- [init(parameterID: CHHapticDynamicParameter.ID, controlPoints: [CHHapticParameterCurve.ControlPoint], relativeTime: TimeInterval)](/documentation/corehaptics/chhapticparametercurve/init(parameterid:controlpoints:relativetime:))
- CHHapticParameterCurve.ControlPoint
Creating a Control Point
Specifying Control Point Coordinates
Describing the Curve
- [var controlPoints: [CHHapticParameterCurve.ControlPoint]](/documentation/corehaptics/chhapticparametercurve/controlpoints)
- var parameterID: CHHapticDynamicParameter.ID
- var relativeTime: TimeInterval
File-based haptics
Game controller haptics
Haptic errors
Inspecting an Error
Error Codes
- case badEventEntry
- case badParameterEntry
- case engineNotRunning
- case engineStartTimeout
- case fileNotFound
- case insufficientPower
- case invalidAudioResource
- case invalidAudioSession
- case invalidEngineParameter
- case invalidEventDuration
- case invalidEventTime
- case invalidEventType
- case invalidParameterType
- case invalidPatternData
- case invalidPatternDictionary
- case invalidPatternPlayer
- case invalidTime
- case memoryError
- case notSupported
- case operationNotPermitted
- case resourceNotAvailable
- case serverInterrupted
- case serverInitFailed
- case unknownError
Initializers
Error Code Constants
- static var badEventEntry: CHHapticError.Code
- static var badParameterEntry: CHHapticError.Code
- static var engineNotRunning: CHHapticError.Code
- static var engineStartTimeout: CHHapticError.Code
- static var fileNotFound: CHHapticError.Code
- static var insufficientPower: CHHapticError.Code
- static var invalidAudioResource: CHHapticError.Code
- static var invalidAudioSession: CHHapticError.Code
- static var invalidEngineParameter: CHHapticError.Code
- static var invalidEventDuration: CHHapticError.Code
- static var invalidEventTime: CHHapticError.Code
- static var invalidEventType: CHHapticError.Code
- static var invalidParameterType: CHHapticError.Code
- static var invalidPatternData: CHHapticError.Code
- static var invalidPatternDictionary: CHHapticError.Code
- static var invalidPatternPlayer: CHHapticError.Code
- static var invalidTime: CHHapticError.Code
- static var memoryError: CHHapticError.Code
- static var notSupported: CHHapticError.Code
- static var operationNotPermitted: CHHapticError.Code
- static var resourceNotAvailable: CHHapticError.Code
- static var serverInterrupted: CHHapticError.Code
- static var serverInitFailed: CHHapticError.Code
- static var unknownError: CHHapticError.Code
Type Properties
Error Codes
- case badEventEntry
- case badParameterEntry
- case engineNotRunning
- case engineStartTimeout
- case fileNotFound
- case insufficientPower
- case invalidAudioResource
- case invalidAudioSession
- case invalidEngineParameter
- case invalidEventDuration
- case invalidEventTime
- case invalidEventType
- case invalidParameterType
- case invalidPatternData
- case invalidPatternDictionary
- case invalidPatternPlayer
- case invalidTime
- case memoryError
- case notSupported
- case operationNotPermitted
- case resourceNotAvailable
- case serverInterrupted
- case serverInitFailed
- case unknownError
Initializers
Variables
- let CHHapticAudioResourceKeyLoopEnabled: String
- let CHHapticAudioResourceKeyUseVolumeEnvelope: String
Type Aliases
---
Extracted from Apple DocC JSON by apple-skills tooling. This is unofficial content. All documentation belongs to Apple Inc.