react-native-haptic-feedback icon indicating copy to clipboard operation
react-native-haptic-feedback copied to clipboard

What is the maximum duration time of vibration in ios

Open davidg327 opened this issue 2 years ago • 5 comments

Description

I am making an exercise app, and I have the haptic activated when the round starts, the problem is that a round lasts 50 seconds, if it passes 25 seconds it stops vibrating, this only happens on iOS, I would like to know if there is a restriction in the library about the maximum haptic time, this problem in android does not happen.

My example code

const options = { enableVibrateFallback: false, ignoreAndroidSystemSettings: true };

const interval = useRef(null);

const hapticLight = () => { trigger("impactLight", options) }

useEffect(() => { interval.current = setInterval(() => { hapticLight() }, 100); return () => clearInterval(interval.current); }, []);

Package version "react": "17.0.2", "react-native": "0.66.5", "react-native-haptic-feedback": "^2.0.0",

Example visual Captura de pantalla 2023-05-25 a la(s) 7 19 09 p m

davidg327 avatar May 26 '23 00:05 davidg327

I have the same issue, is there any limitation, or property that needs to be set?

vanko0309 avatar Aug 21 '23 08:08 vanko0309

A bit of a hack, but I had a similar issue and switched the trigger method to notificationSuccess and no longer had the issue. It felt similar enough for our use case.

siliconivan avatar May 06 '24 03:05 siliconivan

I resolved this with the following patch, hope it's of any use.

react-native-haptic-feedback+2.2.0.patch

diff --git a/node_modules/react-native-haptic-feedback/ios/RNHapticFeedback/RNHapticFeedback.mm b/node_modules/react-native-haptic-feedback/ios/RNHapticFeedback/RNHapticFeedback.mm
index cf75baf..1ca2da3 100644
--- a/node_modules/react-native-haptic-feedback/ios/RNHapticFeedback/RNHapticFeedback.mm
+++ b/node_modules/react-native-haptic-feedback/ios/RNHapticFeedback/RNHapticFeedback.mm
@@ -100,11 +100,10 @@ RCT_EXPORT_METHOD(trigger:(NSString *)type options:(NSDictionary *)options)
         impactGeneratorMap = [[NSMutableDictionary alloc] init];
     if ([impactGeneratorMap objectForKey:key] == nil){
         [impactGeneratorMap setValue:[[UIImpactFeedbackGenerator alloc] initWithStyle:style] forKey:key];
-        [[impactGeneratorMap objectForKey:key] prepare];
     }
-    UIImpactFeedbackGenerator *generator = [impactGeneratorMap objectForKey:key];
-    [generator impactOccurred];
-    [generator prepare];
+    [[impactGeneratorMap objectForKey:key] prepare];
+    [[impactGeneratorMap objectForKey:key] performSelector:@selector(impactOccurred) withObject: nil afterDelay:0.0f];
+    [[impactGeneratorMap objectForKey:key] prepare];
 }
 
 -(void)generateNotificationFeedback:(UINotificationFeedbackType)notificationType{

jpitkanen17 avatar Jul 25 '24 10:07 jpitkanen17

Is this related to a limitation of iOS regarding the haptics? Would be glad to have a reference, but couldn´t find anything. The diff is only triggering the prepare again, or am i missing something @jpitkanen17

mkuczera avatar Aug 03 '24 19:08 mkuczera

Is this related to a limitation of iOS regarding the haptics? Would be glad to have a reference, but couldn´t find anything. The diff is only triggering the prepare again, or am i missing something @jpitkanen17

@mkuczera The extra prepare call might be redundant and something I tried before figuring the real solution out.

The actual solution is this call [[impactGeneratorMap objectForKey:key] performSelector:@selector(impactOccurred) withObject: nil afterDelay:0.0f];

The key difference is the delay 0.0f which overrides the previous haptics call. I tested this with a slider that would stop vibrating on every click after a while and this fixed it. The only "bug" is that sometimes the you can feel the vibration being cancelled.

jpitkanen17 avatar Aug 06 '24 11:08 jpitkanen17