149

I need to make the iPhone vibrate, but I don't know how to do that in Swift. I know that in Objective-C, you just write:

import AudioToolbox
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);

But that is not working for me.

Ahmad F
  • 30,560
  • 17
  • 97
  • 143
Nico Gutraich
  • 1,743
  • 3
  • 12
  • 9
  • Swift has the same function available for you: https://developer.apple.com/library/ios/documentation/AudioToolbox/Reference/SystemSoundServicesReference/index.html#//apple_ref/c/func/AudioServicesPlayAlertSound – Martijn Courteaux Oct 19 '14 at 22:06
  • 1
    Here you will find all codes for each .caf and associated category : https://github.com/TUNER88/iOSSystemSoundsLibrary For example if you want a lighter vibration you can use the code 1003. – O. Boujaouane Jan 02 '19 at 12:29

11 Answers11

244

Short example:

import UIKit
import AudioToolbox

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))            
    }
}

load onto your phone and it will vibrate. You can put it in a function or IBAction as you wish.

Code Update:

 AudioServicesPlayAlertSoundWithCompletion(SystemSoundID(kSystemSoundID_Vibrate)) { }

As apple code docs written:

This function will be deprecated in a future release. Use AudioServicesPlaySystemSoundWithCompletion instead.

NOTE: If vibrate doesn't work. check vibrate is enable in sounds and haptics settings

Community
  • 1
  • 1
Steve Rosenberg
  • 19,348
  • 7
  • 46
  • 53
  • 1
    is there a way to let the phone to vibrate continuously until a button is pressed? – Nicholas Jan 16 '15 at 23:26
  • 3
    What Nicholas asked, also I was wondering if there's a way to make it vibrate in some special pattern. – Nathan McKaskle Jan 30 '15 at 23:20
  • @Nicholas You could try to use timers to play kSystemSoundID_Vibrate in sequence but continuous vibration seems to be a common reason for app store rejection: http://10base-t.com/unofficial-appstore-rejection-criteria/ – MathewS May 23 '15 at 17:59
  • 1
    I know there's a github that shows the System ID's for all of the iPhone audio files and 3 of the vibrate files, but does anyone know how I can access the OTHER vibrate files? I want to use the Staccato vibrate for instance, but I can't figure out the ID, or even if there is one. – jammyman34 Aug 17 '16 at 21:06
  • awesome ... though when I loop the vibrate "sound", it certainly has a threshold (i.e. waits till finishes before vibrating again) ... is there any way around this (i.e. to have the phone constantly buzzing, as opposed to pulsing with a minimal delay between each)? – Chris Allinson Dec 01 '16 at 05:21
  • 1
    @Nicholas if I found an application which asks me to press a button, otherwise it will vibrate forever, I am going to delete it from my device immediately. – user3441734 Jun 07 '17 at 11:48
  • It should be noted, that `AudioServicesPlayAlertSound` will play a sound if vibration is not available on the device while `AudioServicesPlaySystemSound` won't do that. – ndreisg Mar 14 '18 at 16:25
  • 2
    Keep in mind that the device does not vibrate if your app’s audio session is configured with the AVAudioSessionCategoryPlayAndRecord or AVAudioSessionCategoryRecord audio session category. This ensures that vibration doesn’t interfere with audio recording. – FedeH Oct 30 '18 at 11:14
  • Hello @FedeHenze How can I achieve vibration with the audio recording? – Diken Shah Aug 05 '20 at 08:08
88

Swift 4.2 Updated

Just insert code below into your project.

Usage

Vibration.success.vibrate()

Source Code

  enum Vibration {
        case error
        case success
        case warning
        case light
        case medium
        case heavy
        @available(iOS 13.0, *)
        case soft
        @available(iOS 13.0, *)
        case rigid
        case selection
        case oldSchool

        public func vibrate() {
            switch self {
            case .error:
                UINotificationFeedbackGenerator().notificationOccurred(.error)
            case .success:
                UINotificationFeedbackGenerator().notificationOccurred(.success)
            case .warning:
                UINotificationFeedbackGenerator().notificationOccurred(.warning)
            case .light:
                UIImpactFeedbackGenerator(style: .light).impactOccurred()
            case .medium:
                UIImpactFeedbackGenerator(style: .medium).impactOccurred()
            case .heavy:
                UIImpactFeedbackGenerator(style: .heavy).impactOccurred()
            case .soft:
                if #available(iOS 13.0, *) {
                    UIImpactFeedbackGenerator(style: .soft).impactOccurred()
                }
            case .rigid:
                if #available(iOS 13.0, *) {
                    UIImpactFeedbackGenerator(style: .rigid).impactOccurred()
                }
            case .selection:
                UISelectionFeedbackGenerator().selectionChanged()
            case .oldSchool:
                AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
            }
        }
    }
muhasturk
  • 2,534
  • 20
  • 16
  • 6
    Don't forget to add 'import AVFoundation' in order to use .oldSchool vibration :) – atereshkov Oct 02 '18 at 12:36
  • Except .oldSchool remaining cases not working I tested in iPhone 6 physical device any help? – Sai kumar Reddy Jan 24 '20 at 06:32
  • 1
    You should explain that FeedbackGenerator is haptic and it came with iPhone 7. You can also have only one line each case : UIImpactFeedbackGenerator(style: .heavy).impactOccurred() – Medhi Apr 03 '20 at 09:08
  • The only one that's working for me is `.oldSchool`. I'm using an iPhone 6s with iOS 14. The iPhone 6s *does* have a taptic engine and it's used when toggling the silent switch. Is it disabled because Apple want to make the iPhone 7 look better? Or maybe I'm just doing something wrong. **Edit:** Nevermind, Michael's answer worked for me. – Indiana Kernick Jan 28 '21 at 08:36
82

In iOS 10 on iPhone 7 or 7 Plus, try:

let generator = UIImpactFeedbackGenerator(style: .heavy)
generator.impactOccurred()
Tulleb
  • 8,919
  • 8
  • 27
  • 55
Adam Smaka
  • 5,977
  • 3
  • 50
  • 55
  • 1
    we all use iOS 10, don't we? it's the newest, the best and free version of the system. everyone should update, there is no compromises of having it. – Adam Smaka Dec 03 '16 at 09:03
  • 13
    Beyond iOS 10, this is only a feature that will work with iPhone 7 or later. It will be ignored on devices older than the iPhone 7. – C6Silver Feb 22 '17 at 06:45
  • @C6Silver You're true. It isn't working on iPhone 4s,5,5s,5c and 6. These devices I have tested. – Rocky Balboa Mar 09 '17 at 10:16
59

Other vibration types:

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)

Michael
  • 9,639
  • 3
  • 64
  • 69
32

Swift 4.2, 5.0

 if #available(iOS 10.0, *) {
      UIImpactFeedbackGenerator(style: .light).impactOccurred()
   } 

You can also choose other styles like

    style: .heavy
    style: .medium

    //Note: soft and rigid available in only iOS 13.0
    style: .soft
    style: .rigid
Rashid Latif
  • 2,809
  • 22
  • 26
26

For iOS 10.0+ You can try UIFeedbackGenerator

Simple viewController above, just replace your view controller in your test "single view app"

import UIKit

class ViewController: UIViewController {

    var i = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        let btn = UIButton()
        self.view.addSubview(btn)
        btn.translatesAutoresizingMaskIntoConstraints = false

        btn.widthAnchor.constraint(equalToConstant: 160).isActive = true
        btn.heightAnchor.constraint(equalToConstant: 160).isActive = true
        btn.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        btn.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true

        btn.setTitle("Tap me!", for: .normal)
        btn.setTitleColor(UIColor.red, for: .normal)
        btn.addTarget(self, action: #selector(tapped), for: .touchUpInside)
    }

    @objc func tapped() {
        i += 1
        print("Running \(i)")

        switch i {
        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()
            i = 0
        }
    }
}
Kiryl Bielašeŭski
  • 2,663
  • 2
  • 28
  • 40
19

We can do this in Xcode7.1

import UIKit
import AudioToolbox


class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)
    }
}
ken0nek
  • 517
  • 5
  • 9
6

You can vibrate the phone using either AudioServices or Haptic Feedback.

// AudioServices
AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))

// Haptic Feedback
UIImpactFeedbackGenerator(style: .medium).impactOccurred()

Checkout my open source framework Haptica, it supports both Haptic Feedback, AudioServices and unique vibrations patterns. Works on Swift 4.2, Xcode 10

efremidze
  • 2,640
  • 1
  • 25
  • 35
3
import AudioToolbox

extension UIDevice {
    static func vibrate() {
        AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
    }
}

Now you can just call UIDevice.vibrate() as needed.

Mohammad Razipour
  • 3,643
  • 3
  • 29
  • 49
2

UINotificationFeedbackGenerator available from iOS 10 and work with Haptic v2, we can check this:

  let feedbackSupportLevel = UIDevice.current.value(forKey: "_feedbackSupportLevel") as? Int
        if #available(iOS 10.0, *), let feedbackSupportLevel = feedbackSupportLevel, feedbackSupportLevel > 1 {
            do { // 1
                let generator = UIImpactFeedbackGenerator(style: .medium)
                generator.impactOccurred()
            }

            do { // or 2
                let generator = UINotificationFeedbackGenerator()
                generator.notificationOccurred(.success)
            }
        } else {
            AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))
        }
1
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
Dhaval H. Nena
  • 3,992
  • 1
  • 37
  • 50
  • 1
    You should highlight in your answer that you are using [`AudioServicesPlaySystemSound`](https://developer.apple.com/documentation/audiotoolbox/1405248-audioservicesplaysystemsound) instead of top answer's [`AudioServicesPlayAlertSound`](https://developer.apple.com/documentation/audiotoolbox/1405202-audioservicesplayalertsound). – Cœur Aug 25 '17 at 10:16