How to check if the Haptic Engine (UIFeedbackGenerator) is supported

I am wondering how we can check if the new iOS 10 API UIFeebackGenerator on the current device. There are a few more things we need to check:

  • The device must be running iOS 10.0 or later.
  • The device must be iPhone 7 or later.
  • Haptic Engine must be enabled in the settings

The first two checks can be achieved using the #available(iOS 10, *) operator and the discovery of a (hacker) device, but the last, it seems, cannot be verified.

Does anyone know a solution for this? Or maybe we need to file Apple Radar for this. Thanks!

+11
ios ios10 haptic-feedback
source share
4 answers

Based on the Apple UIFeedbackGenerator documentation , similar to iOS, this is for you.

Note that calling these methods does not directly reproduce haptics. Instead, he informs the system of the event. The system then determines whether to play haptics based on the device , the state of the applications, the amount of battery remaining and other factors.

For example, only tactical feedback is currently being played:

On a device with Taptic Engine support (iPhone 7 and iPhone 7 Plus).

When the application runs in the foreground.

If the "System Preferences" option is enabled.

Even if you don’t need to worry about checking if the device can do tactical feedback, you still need to make sure that it is only called from iOS 10 or higher, so you can do this with this:

  if #available(iOS 10,*) { // your haptic feedback method } 

Here's a brief description of the various haplotic feedback options available in iOS 10.

+6
source share

There is an undocumented "private thing":

 UIDevice.currentDevice().valueForKey("_feedbackSupportLevel"); 

it returns 2 for tactile feedback devices - the iPhone 7/7 +, so you can easily use this to generate Haptic feedback:

 let generator = UIImpactFeedbackGenerator(style: .heavy) generator.prepare() generator.impactOccurred() 

returns 1 for iPhone 6S, here is the reserve for creating taptic:

 import AudioToolbox AudioServicesPlaySystemSound(1519) // Actuate `Peek` feedback (weak boom) AudioServicesPlaySystemSound(1520) // Actuate `Pop` feedback (strong boom) AudioServicesPlaySystemSound(1521) // Actuate `Nope` feedback (series of three weak booms) 

and returns 0 for iPhone 6 or older devices. Since this is a kind of undocumented thing, it can block you at the review stage, although I managed to pass the test and send the application with such a check.

More details: http://www.mikitamanko.com/blog/2017/01/29/haptic-feedback-with-uifeedbackgenerator/

+12
source share

You know that your device supports the Haptic vibration effect or not with the code below,

 UIDevice.currentDevice().valueForKey("_feedbackSupportLevel"); 

These methods seem to return:

  • 0 = Ribbon unavailable

  • 1 = First generation (tested on iPhone 6s) ... which DOES NOT support UINotificationFeedbackGenerator, etc.

  • 2 = Second generation (tested on iPhone 7) ... which supports it.

it returns 2 for tactile feedback devices - iPhone 7/7 + or higher, so you can easily use this to generate Haptic feedback

0
source share

This will work for iPhone 7 and above.

  var count = 0 override func viewDidLoad() { super.viewDidLoad() let myButton = UIButton(frame: CGRect(x: 0, y: 100, width: 100, height: 50)) myButton.setTitleColor(UIColor.green, for: .normal) myButton.setTitle("Press ME", for: .normal) myButton.addTarget(self, action: #selector(myButtonTapped), for: .touchUpInside) self.view.addSubview(myButton) } @objc func myButtonTapped() { count += 1 print("Count \(count)") switch count { case 1: let generator = UINotificationFeedbackGenerator() generator.notificationOccurred(.error) case 2: let generator = UINotificationFeedbackGenerator() generator.notificationOccurred(.success) case 3: let generator = UINotificationFeedbackGenerator() generator.notificationOccurred(.warning) case 4: let generator = UIImpactFeedbackGenerator(style: .light) generator.impactOccurred() case 5: let generator = UIImpactFeedbackGenerator(style: .medium) generator.impactOccurred() case 6: let generator = UIImpactFeedbackGenerator(style: .heavy) generator.impactOccurred() default: let generator = UISelectionFeedbackGenerator() generator.selectionChanged() count = 0 } } 
0
source share