mkuczera / react-native-haptic-feedback

React-Native Haptic Feedback for iOS with Android similar behaviour.
MIT License
850 stars 103 forks source link

Fallback for devices that doesn't support Taptic Engine #9

Closed ma-pe closed 6 years ago

ma-pe commented 6 years ago

The Taptic Engine is supported from iPhone 6S. The iPhone SE for example supports the latest iOS, but doesn't support haptic feedback. If I trigger a feedback nothing happens.

I see two alternatives that'd improve this library:

1) Trigger a default vibration if the taptic engine isn't present.

2) Expose a function that tells if the taptic engine is available (the current function only checks for iOS >= 10.0). If not present the developer may decide to fallback to a default vibration.

ma-pe commented 6 years ago

This should be helpful determining the support of the taptic engine: https://stackoverflow.com/a/42057620/5841225

mkuczera commented 6 years ago

Hi @ma-pe ,

thanks for your feedback. I will just check the corresponding fallbacks for the specific devices and update the library. Otherwise if you can open a PR regarding these changes, i would be pretty thankful. ;)

Greetings from Hamburg

ma-pe commented 6 years ago

Exciting! I am from Hamburg too. Have you been to one of the react-native meetups?

I read a little further into this and there doesn't seem to be a good way of detecting support for the taptic-engine. There is a private variable that could be used, but will probably prevent your app from passing the apple review process (http://www.mikitamanko.com/blog/2017/01/29/haptic-feedback-with-uifeedbackgenerator/).

I fixed it on the javascript-side by comparing the current device to a list of supported devices. This isn't optimal (has to be touched with every device release), but it works for now. As a fallback I use the vibration api:

export const isHapticFeedbackSupported =
  Platform.OS === 'android' ||
  [
    'iPhone9,1', // iPhone 7
    'iPhone9,2', // iPhone 7 Plus
    'iPhone9,3', // iPhone 7
    'iPhone9,4', // iPhone 7 Plus
    'iPhone10,1', // iPhone 8
    'iPhone10,2', // iPhone 8 Plus
    'iPhone10,3', // iPhone X
    'iPhone10,4', // iPhone 8
    'iPhone10,5', // iPhone 8 Plus
    'iPhone10,6', // iPhone X
  ].includes(DeviceInfo.getDeviceId());

const triggerFeedback = function() {
  if (isHapticFeedbackSupported) {
    ReactNativeHapticFeedback.trigger('impactHeavy');
  } else {
    Vibration.vibrate();
  }
};

You could add this comparison to the library, but I am not sure we'd want that.

mkuczera commented 6 years ago

Unfortunately not. We had one in our office where i attended, but couldn´t find time for the other ones.

I read a little bit about the issue. The private variable solution should be fine. Even when it´s not officially in the Apple docs, it should not harm the iOS Review process. I will try this out in our App first, but can´t see any real reason that it´s harming any guideline.

After the check i can fall back to AudioServicesPlaySystemSoundWithVibration with a custom pattern similar to the current "faked" Android behaviour.

mkuczera commented 6 years ago

okay, nevermind. just checked this: "this class is not key value coding-compliant for the key _feedbackSupportLevel."

will check for other usages maybe

mkuczera commented 6 years ago

Fixed in Release 1.1.2 #10