Make Your iOS App ‘Feel’ Better — A Guide Over Taptic Engine & Haptic Feedback

Update: Checkout my open source framework, Piano. It makes using the Taptic Engine much easier, allowing you to create patterns of sound patterns and vibrations.

If you haven’t downloaded iTranslate’s Converse app, I suggest you do so now and play around with it — it’s a very well designed & polished app. What really stood out to me in Converse’s user interactions was the subtle vibrations that came with each swipe and transition between views in the app — something you’ll notice adds a spirited feeling to the user experience, yet doesn’t obstruct the seamlessness of the interface. If you’ve already seen this wonderful talk over designing sound for apps at WWDC 2017, then you’ll know how non-visible aspects of your app can have a tremendous impact on your app’s user experience, and in many cases can be the difference between a good app and a great app.

Basic Vibration (Supported by All iPhone Devices)

In order to use the device vibrator, we must first import AudioToolbox.AudioServices, allowing us to use the AudioServicesPlaySystemSound() and AudioServicesPlaySystemSoundWithCompletion(:) functions. These functions take a parameter of type SystemSoundID, which is just a typealias for UInt32, and represents a vibration pattern. In the snippet above, our SystemSoundID is kSystemSoundID_Vibrate which is simply 4095, representing a linear 1-second vibration that you’re probably familiar with. But wait, this means that we can pass other numbers into this parameter to play different vibrations, right? Correct! This is where Taptic Engine comes in.

Taptic Engine (iPhone 6S, 6S Plus, and above)

With the release of the iPhone 6S and 6S Plus, Apple introduced 3D Touch, and to complement the new ‘depths’ added to the iOS interface, Apple replaced the standard vibrator with a Taptic Engine which provides tactile sensations in the form of vibrations (called haptic signals.) Remember how the old basic vibration, kSystemSoundID_Vibrate, was just a name for the number 4095? The new haptic signals can be accessed similarly with their associated UInt32s.

iTranslate’s Converse app uses the ‘Peek’ vibration when switching between view controllers, and the ‘Pop’ vibration when the user starts to record something to translate.

Haptic Feedback (iPhone 7, 7 Plus, and above)

Apple started taking device vibrations more seriously when they removed the home button in the iPhone 7 and 7 Plus. The various haptic signals needed for all the actions in this new button-less device required Apple to build a 2nd generation of the Taptic Engine. Apple also created several frameworks in a bundle called Haptic Feedback to easily use this new technology. These frameworks are only available in iOS 10.

You can view a demo of all the various signals that Haptic Feedback has to offer on Apple’s iOS Human Interface Guidelines.


Indicates that a task or action, such as depositing a check, has completed, failed, or produced a warning. It has three variations: .success.warning, and .error.


Provides a physical means of complementing the visual experience. For example, the user might feel a thud when a view slides into place or two objects collide. It has three variations: .light.medium, and .heavy.

You’ll notice that UIImpactFeedbackGenerator is similar in concept to UINotificationFeedbackGenerator, but has minor syntactical differences. I find creating Impact Feedback Generators with tuples is the simplest means of working with all the variations of impact the signals have:


Indicates that the selection is actively changing. For example, the user feels light taps while scrolling a picker wheel. This feedback is intended for communicating movement through a series of discrete values, not making or confirming a selection.

It’s important to note that iOS automatically uses Haptic Feedback for common controls like UIPickerViews and the Keyboard, but it may be important to implement selection feedback for custom controls and interactions in your app.

Properly Using The Haptic Feedback Frameworks

When you instantiate a Haptic Feedback framework, the Taptic Engine essentially ‘turns on’. Apple recommends you deallocate your Haptic Feedback framework class instance when you can — this lets the Taptic Engine return to its idle state and preserves the user’s device’s battery life. Here is an example from Apple’s documentation of properly using a UISelectionFeedbackGenerator:

Using the Appropriate Method for the User’s Device

Since the various functions implemented above require specific versions of the iPhone, we’ll need a way to check the user’s device model in order to use Haptic Feedback whenever we can and then fallback to the older generation Taptic Engine methods if the device doesn’t support it.

There’s a lot of ambiguity when it comes to figuring out if a device has Taptic Engine and/or Haptic Feedback. This twitter thread shines light on a private Apple API that gives us info about the device’s Taptic Engine. Here’s an example of it in action:

Although using private APIs is known to result in App Store rejection, some developers report using this method and not having their apps being rejected. If you don’t like living on the edge, here’s a perfectly legal extension for UIDevice that tells you everything you need to know:

And here’s an example of this extension in action:


I recommend downloading the source code for this guide in this sweet example app. It contains all the possible vibration patterns iOS allows (there’s not a lot of documentation on these codes, I had to do a bit of digging for some of them.)

Haptic signals are a great way to complement your app’s interface and create a stunning user experience overall. Although haptic signals require fairly new device models, using the Taptic Engine is a sure fire way to make your app stand out, and it’s only a matter of time before everyone upgrades to a device that has it.

Don’t hesitate to reach out to me on Twitter with any questions or concerns!