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

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

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

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

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

3 ответа

Решение

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

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

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

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

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

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

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

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

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

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

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

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

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

возвращает 1 для iPhone 6S, вот запасной вариант для создания ленты:

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/

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

iOS 13, Swift 5

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

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

extension UIDevice {

 static var isHapticsSupported : Bool {

    let feedback = UIImpactFeedbackGenerator(style: .heavy)
    feedback.prepare()
    var string = feedback.debugDescription
    string.removeLast()
    let number = string.suffix(1)

    if number == "1" {
        return true
    } else {
        return false
    }
  }
}

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

UIDevice.isHapticsSupported 

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

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

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

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

  • 0 = Лента недоступна

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

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

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

Это будет работать для 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
    }
}
Другие вопросы по тегам