Skip to content

iOS SDK

The Pulsar iOS SDK provides haptic feedback through three building blocks: Presets, PatternComposer, and RealtimeComposer. All are accessed through the main Pulsar class.

  • iOS 13.0+
  • Swift 5.9+

Add Pulsar as a Swift Package dependency in Xcode:

  1. Go to File > Add Package Dependencies…
  2. Enter the repository URL
  3. Select the Pulsar library product

Or add it to your Package.swift:

dependencies: [
.package(url: "https://github.com/software-mansion-labs/pulsar-ios")
]

Create a Pulsar instance to access all SDK features:

import Pulsar
let pulsar = Pulsar()

A collection of ready-to-use haptic patterns accessed through pulsar.getPresets().

let presets = pulsar.getPresets()
MethodDescription
afterglow()A three-beat phrase that dissolves gently, ideal for soft endings or gradually quieting feedback.
aftershock()A firm opening that settles calmly, ideal for transitions needing a strong start and a gentle finish.
alarm()Relentless and urgent, best for critical errors or emergencies that require immediate attention.
anvil()The full weight of a massive collision, conveys sheer physical force and momentum.
applause()A growing wave of appreciation, ideal for celebratory moments or social approval.

Example

let presets = pulsar.getPresets()
presets.dogBark()

Plays the platform’s platform haptic feedback presets.

MethodDescription
systemImpactHeavy()UIImpactFeedbackGenerator.heavy
systemImpactLight()UIImpactFeedbackGenerator.light
systemImpactMedium()UIImpactFeedbackGenerator.medium
systemImpactRigid()UIImpactFeedbackGenerator.rigid
systemImpactSoft()UIImpactFeedbackGenerator.soft

Example

let presets = pulsar.getPresets()
presets.systemImpactHeavy()

You can also play a preset by its string name using getByName(_:). This returns a Preset? that you call play() on.

Available names:

  • Afterglow
  • Aftershock
  • Alarm
  • Anvil
  • Applause
  • Ascent
  • BalloonPop
  • Barrage

Example

let presets = pulsar.getPresets()
// Direct call
presets.dogBark()
// By name
presets.getByName("Success")?.play()

Composes and plays custom haptic patterns. Get a new instance from pulsar.getPatternComposer(). Each call returns a fresh composer, so you can manage multiple patterns independently.

let composer = pulsar.getPatternComposer()

Parses a PatternData object and prepares it for playback.

func parsePattern(hapticsData: PatternData)

Parses and immediately plays a pattern. Equivalent to calling parsePattern followed by play.

func playPattern(hapticsData: PatternData)

Plays the previously parsed pattern.

func play()

Stops all playback.

func stop()
let composer = pulsar.getPatternComposer()
let pattern = PatternData(
continuousPattern: ContinuousPattern(
amplitude: [
ValuePoint(time: 0, value: 0),
ValuePoint(time: 200, value: 1),
ValuePoint(time: 400, value: 0),
],
frequency: [
ValuePoint(time: 0, value: 0.3),
ValuePoint(time: 400, value: 0.8),
]
),
discretePattern: [
DiscretePoint(time: 0, amplitude: 1, frequency: 0.5),
DiscretePoint(time: 100, amplitude: 0.5, frequency: 0.5),
]
)
composer.playPattern(hapticsData: pattern)

Provides real-time haptic control with live amplitude and frequency modulation. Useful for gesture-driven or continuously evolving haptic experiences. Get the shared instance from pulsar.getRealtimeComposer().

let realtime = pulsar.getRealtimeComposer()

Updates the ongoing haptic with new amplitude and frequency values. Automatically starts playback if it is not already active. Values are clamped to the 0-1 range.

func set(amplitude: Float, frequency: Float)

Plays a single discrete haptic event.

func playDiscrete(amplitude: Float = 1.0, frequency: Float = 0.5)

Stops the active continuous haptic.

func stop()

Returns true if a continuous haptic is currently playing.

var isActive: Bool { get }
let realtime = pulsar.getRealtimeComposer()
// Start a continuous haptic
realtime.set(amplitude: 0.5, frequency: 0.8)
// Update parameters over time
realtime.set(amplitude: 1.0, frequency: 0.3)
// Play a one-off discrete event
realtime.playDiscrete(amplitude: 0.7, frequency: 0.5)
// Stop
realtime.stop()

Configuration methods available directly on the Pulsar instance.

MethodDescription
enableHaptics(state: Bool)Enable or disable all haptic feedback
enableSound(state: Bool)Enable or disable audio simulation
enableCache(state: Bool)Enable or disable preset caching
clearCache()Clear the preset cache
preloadPresets(presetNames: [String])Preload presets by name for faster playback
stopHaptics()Stop all currently playing haptics
shutDownEngine()Shut down the haptic engine
isHapticsSupported() -> BoolCheck if the device supports haptics
let pulsar = Pulsar()
// Preload frequently used presets
pulsar.preloadPresets(presetNames: ["Earthquake", "Success"])
// Disable haptics temporarily
pulsar.enableHaptics(state: false)
// Check device support
if pulsar.isHapticsSupported() {
pulsar.getPresets().success()
}

Describes a complete haptic pattern with discrete pulses and continuous envelope curves.

class PatternData: NSObject, Codable {
let continuousPattern: ContinuousPattern
let discretePattern: [DiscretePoint]
init(
continuousPattern: ContinuousPattern,
discretePattern: [DiscretePoint]
)
}

Represents continuous haptic curves for amplitude and frequency.

class ContinuousPattern: NSObject, Codable {
let amplitude: [ValuePoint]
let frequency: [ValuePoint]
init(amplitude: [ValuePoint], frequency: [ValuePoint])
}

A single point in a continuous curve.

class ValuePoint: NSObject, Codable {
let time: Double // Milliseconds from pattern start
let value: Float // Normalized value (0-1)
init(time: Double, value: Float)
}

A single discrete haptic event.

class DiscretePoint: NSObject, Codable {
let time: Double // Milliseconds from pattern start
let amplitude: Float // Intensity (0-1)
let frequency: Float // Sharpness (0-1)
init(time: Double, amplitude: Float, frequency: Float)
}

Use discretePattern for distinct taps and impacts. Use continuousPattern envelopes to shape a sustained haptic over time.

The protocol that all preset implementations conform to.

protocol Preset {
func play()
static func getInstance(haptics: Pulsar) -> Preset
static var name: String { get }
}