Skip to content

Commit 59b9764

Browse files
committed
fix(ios): prevent thread overload by reusing CHHapticEngine
1 parent 927f549 commit 59b9764

File tree

1 file changed

+51
-9
lines changed

1 file changed

+51
-9
lines changed

haptics/ios/Sources/HapticsPlugin/Haptics.swift

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,45 @@ import CoreHaptics
66

77
var selectionFeedbackGenerator: UISelectionFeedbackGenerator?
88

9+
// Haptic Engine Management
10+
private var hapticEngine: CHHapticEngine?
11+
private var idleTimer: Timer?
12+
private let idleInterval: TimeInterval = 5.0 // Engine will shut down after 5 seconds of inactivity
13+
14+
/**
15+
* Initializes the haptic engine and starts it.
16+
*/
17+
private func initializeEngine() {
18+
if CHHapticEngine.capabilitiesForHardware().supportsHaptics {
19+
do {
20+
hapticEngine = try CHHapticEngine()
21+
try hapticEngine?.start()
22+
} catch {
23+
print("Error initializing haptic engine: \(error)")
24+
hapticEngine = nil
25+
}
26+
}
27+
}
28+
29+
/**
30+
* Reset the idle timer each time a haptic event is fired.
31+
*/
32+
private func resetIdleTimer() {
33+
idleTimer?.invalidate()
34+
idleTimer = Timer.scheduledTimer(withTimeInterval: idleInterval, repeats: false) { [weak self] _ in
35+
self?.shutdownEngine()
36+
}
37+
}
38+
39+
/**
40+
* Shuts down the haptic engine if it is not in use.
41+
*/
42+
private func shutdownEngine() {
43+
hapticEngine?.stop(completionHandler: nil)
44+
hapticEngine = nil
45+
}
46+
47+
948
@objc public func impact(_ impactStyle: UIImpactFeedbackGenerator.FeedbackStyle) {
1049
let generator = UIImpactFeedbackGenerator(style: impactStyle)
1150
generator.impactOccurred()
@@ -38,16 +77,19 @@ import CoreHaptics
3877

3978
@objc public func vibrate(_ duration: Double) {
4079
if CHHapticEngine.capabilitiesForHardware().supportsHaptics {
80+
// Reuse the existing engine or initialize a new one if needed.
81+
if hapticEngine == nil {
82+
initializeEngine()
83+
}
84+
// Reset the idle timer so the engine remains alive.
85+
resetIdleTimer()
86+
87+
guard let engine = hapticEngine else {
88+
vibrate() // fallback if the engine couldn’t be created
89+
return
90+
}
91+
4192
do {
42-
let engine = try CHHapticEngine()
43-
try engine.start()
44-
engine.resetHandler = { [] in
45-
do {
46-
try engine.start()
47-
} catch {
48-
self.vibrate()
49-
}
50-
}
5193
let intensity = CHHapticEventParameter(parameterID: .hapticIntensity, value: 1.0)
5294
let sharpness = CHHapticEventParameter(parameterID: .hapticSharpness, value: 1.0)
5395

0 commit comments

Comments
 (0)