fix(ios): prevent thread overload by reusing CHHapticEngine#24
Open
GorkaMinus wants to merge 1 commit intoionic-team:mainfrom
Open
fix(ios): prevent thread overload by reusing CHHapticEngine#24GorkaMinus wants to merge 1 commit intoionic-team:mainfrom
GorkaMinus wants to merge 1 commit intoionic-team:mainfrom
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR addresses an issue where calling
Haptics.vibrate()rapidly (e.g., from a fast-scrolling picker in my case) causes the app to hang or crash on iOS. The problem stems from creating a newCHHapticEngineinstance on each call, which leads to excessive thread creation and eventual system overload.Solution:
CHHapticEngineinstance across multiple vibration callsduration + 5sof inactivity, so the idle countdown starts after the vibration finishesresetHandler(restarts engine after server recovery) andstoppedHandler(clears the reference on external stops like audio interruptions or app suspension)Change Type
Rationale / Problems Fixed
Continuation of ionic-team/capacitor-plugins#2340, moved here per maintainer guidance since the haptics plugin now lives in its own repository.
Related: #7
Creating a new
CHHapticEnginepervibrate()call spawns threads that accumulate faster than the system can reclaim them. Under rapid-fire usage (pickers, scroll-driven haptics), this leads to thread exhaustion, UI freezes, and eventual crashes.Tests or Reproductions
Haptics.vibrate()from a picker/scroll, confirm no freeze or crashvibrate(duration)with a long duration (e.g. 5s), confirm vibration completes fully before engine shuts downAudioServicesPlayAlertSoundon devices without haptic supportPlatforms Affected
Notes / Comments
This also addresses review feedback from the original PR (ionic-team/capacitor-plugins#2340):
supportsHapticscheck insideinitializeEngine()since it's already guarded in the callerduration + 5s) instead of a flat 5s countdownresetHandlerandstoppedHandlerfor proper engine lifecycle management following Apple's recommended patterns