Как проверить, поддерживается ли Haptic Engine (UIFeedbackGenerator)

Мне интересно, как мы можем проверить, доступен ли новый API iOS 10 UIFeebackGenerator на текущем устройстве. Есть еще кое-что, что нам нужно проверить:

  1. Устройство должно работать под управлением iOS 10.0 или более поздней версии.
  2. Устройство должно быть iPhone 7 или более поздней версии.
  3. Haptic Engine должен быть включен в настройках.

Первые две проверки можно выполнить с помощью оператора #available(iOS 10, *) и (хакерского) обнаружения устройства, но последний, похоже, не поддается проверке.

Кто-нибудь знает решение для этого? Или, может быть, нам нужно зарегистрировать Apple Radar для этого. Спасибо!


person Hans Knöchel    schedule 03.01.2017    source источник


Ответы (6)


Основываясь на документации Apple UIFeedbackGenerator, похоже, что iOS сделает это за вас.

Обратите внимание, что вызов этих методов не воспроизводит тактильные сигналы напрямую. Вместо этого он информирует систему о событии. Затем система определяет, следует ли воспроизводить тактильные ощущения, в зависимости от устройства, состояния приложения, оставшегося заряда батареи и других факторов.

Например, тактильная обратная связь в настоящее время воспроизводится только:

На устройстве с поддерживаемым Taptic Engine (iPhone 7 и iPhone 7 Plus).

Когда приложение работает на переднем плане.

Когда параметр System Haptics включен.

Даже если вам не нужно беспокоиться о проверке того, может ли устройство выполнять тактильную обратную связь, вам все равно нужно убедиться, что оно вызывается только с iOS 10 или более поздней версии, поэтому вы можете сделать это с помощью этого:

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

Вот краткий обзор различных вариантов тактильной обратной связи, доступных в iOS 10.

person Adrian    schedule 03.01.2017
comment
Что делать, если вы хотите вернуться к использованию старого AudioServicesPlaySystemSound, если движок Taptic недоступен? - person Daniel Larsson; 31.01.2017
comment
@DanielLarsson Это может быть полезно. Вы хотите проверить iOS до версии 10. nshipster.com/swift-system-version -проверка - person Adrian; 31.01.2017
comment
@Adrian только что протестировал iOS 9. Кажется, он просто ничего не делает (не приводит к сбою приложения). - person Idan; 09.05.2017

Есть какая-то недокументированная "частная вещь":

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

он возвращает 2 для устройств с тактильной обратной связью — iPhone 7/7+, поэтому вы можете легко использовать это для создания тактильной обратной связи:

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

возвращает 1 для iPhone 6S, вот запасной вариант для создания 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)

и возвращает 0 для устройств iPhone 6 и старше. Поскольку это недокументированная вещь, она может заблокировать вас на этапе проверки, хотя я смог пройти проверку и отправить приложение с такой проверкой.

Дополнительные сведения: http://www.mikitamanko.com/blog/2017/01/29/haptic-feedback-with-uifeedbackgenerator/

person Mikita Manko    schedule 05.02.2017
comment
У меня по-прежнему не вибрирует на iPhoneSE2015 iOS 13.4.1. Запускает код без ошибок - person Curtis; 01.04.2021

Начиная с iOS 13 вы можете проверить это очень просто. Согласно странице документации, все, что вам нужно сделать, это:

iOS 13 и новее, Swift 5.3

import CoreHaptics

var supportsHaptics: Bool = false
...
// Check if the device supports haptics.
let hapticCapability = CHHapticEngine.capabilitiesForHardware()
supportsHaptics = hapticCapability.supportsHaptics

Документация: Подготовка вашего приложения для воспроизведения Haptics

person Witek Bobrowski    schedule 05.03.2020
comment
Это должен быть принятый ответ. - person Rakesha Shastri; 25.01.2021

Я сделал расширение для UIDevice без использования частного API

extension UIDevice {
    
        static var isHapticsSupported : Bool {
            let feedback = UIImpactFeedbackGenerator(style: .heavy)
            feedback.prepare()
            return feedback.description.hasSuffix("Heavy>")
        }
    }

и вы используете его так:

UIDevice.isHapticsSupported 

возвращает true или false

person Rom4in    schedule 20.02.2019
comment
Это не работает для меня. На iPad он возвращает true, но iPad не поддерживает тактильные ощущения. - person Ailton Vieira Pinto Filho; 24.05.2020

Вы знаете, что ваше устройство поддерживает эффект тактильной вибрации или нет с кодом ниже,

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

Эти методы, похоже, возвращаются:

  • 0 = Taptic недоступен

  • 1 = Первое поколение (протестировано на iPhone 6s)... которое НЕ поддерживает UINotificationFeedbackGenerator и т. д.

  • 2= Второе поколение (проверено на iPhone 7)... которое поддерживает его.

он возвращает 2 для устройств с тактильной обратной связью — iPhone 7/7+ или выше, поэтому вы можете легко использовать это для создания тактильной обратной связи.

person Ashish    schedule 20.04.2018
comment
Извините, но это частный API и вызовет отказы, если не будет запутан. Но для внутренних приложений это полезное решение! - person Hans Knöchel; 27.04.2018
comment
Их использование может привести к тому, что ваше приложение будет отклонено Apple во время проверки приложений в App Store, но в настоящее время, похоже, нет другого пути. - person Ashish; 25.02.2019

Это будет работать для iPhone 7 и выше.

 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
    }
}
person Yogendra Singh    schedule 12.12.2018