Skip to content

Commit 439f39b

Browse files
GorkaMinusGorka Max Woischwill
authored andcommitted
fix(ios): prevent thread overload by reusing CHHapticEngine
1 parent d04a74e commit 439f39b

File tree

1 file changed

+50
-9
lines changed

1 file changed

+50
-9
lines changed

haptics/ios/Sources/HapticsPlugin/Haptics.swift

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

77
var selectionFeedbackGenerator: UISelectionFeedbackGenerator?
88

9+
private var hapticEngine: CHHapticEngine?
10+
private var idleTimer: Timer?
11+
private let idleInterval: TimeInterval = 5.0
12+
13+
private func initializeEngine() {
14+
do {
15+
let engine = try CHHapticEngine()
16+
engine.resetHandler = { [weak self] in
17+
do {
18+
try self?.hapticEngine?.start()
19+
} catch {
20+
self?.hapticEngine = nil
21+
}
22+
}
23+
engine.stoppedHandler = { [weak self] _ in
24+
self?.hapticEngine = nil
25+
}
26+
try engine.start()
27+
hapticEngine = engine
28+
} catch {
29+
hapticEngine = nil
30+
}
31+
}
32+
33+
private func resetIdleTimer(after duration: TimeInterval) {
34+
idleTimer?.invalidate()
35+
idleTimer = Timer.scheduledTimer(
36+
withTimeInterval: duration + idleInterval, repeats: false
37+
) { [weak self] _ in
38+
self?.shutdownEngine()
39+
}
40+
}
41+
42+
private func shutdownEngine() {
43+
idleTimer?.invalidate()
44+
idleTimer = nil
45+
hapticEngine?.stop(completionHandler: nil)
46+
hapticEngine = nil
47+
}
48+
949
@objc public func impact(_ impactStyle: UIImpactFeedbackGenerator.FeedbackStyle) {
1050
let generator = UIImpactFeedbackGenerator(style: impactStyle)
1151
generator.impactOccurred()
@@ -38,16 +78,17 @@ import CoreHaptics
3878

3979
@objc public func vibrate(_ duration: Double) {
4080
if CHHapticEngine.capabilitiesForHardware().supportsHaptics {
81+
if hapticEngine == nil {
82+
initializeEngine()
83+
}
84+
resetIdleTimer(after: duration)
85+
86+
guard let engine = hapticEngine else {
87+
vibrate()
88+
return
89+
}
90+
4191
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-
}
5192
let intensity = CHHapticEventParameter(parameterID: .hapticIntensity, value: 1.0)
5293
let sharpness = CHHapticEventParameter(parameterID: .hapticSharpness, value: 1.0)
5394

0 commit comments

Comments
 (0)