Сделать iPhone вибрирующим

Как iPhone может быть настроен на вибрацию один раз?

Например, когда игрок теряет жизнь или игра заканчивается, iPhone должен вибрировать.

Ответ 1

От " iPhone Tutorial: лучший способ проверить возможности устройств iOS:

Есть две, казалось бы, похожие функции, которые принимают параметр kSystemSoundID_Vibrate:

1) AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
2) AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

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

Сначала добавьте фреймворк AudioToolbox AudioToolbox.framework к вашей цели на этапах сборки.

Затем импортируйте этот файл заголовка:

#import <AudioToolbox/AudioServices.h>

Ответ 2

Свифт 2. 0+

AudioToolbox теперь представляет kSystemSoundID_Vibrate как тип SystemSoundID, поэтому код выглядит так:

import AudioToolbox.AudioServices

AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)

Вместо того, чтобы идти через дополнительный шаг броска

(Реквизит @Dov)

Оригинальный ответ (Swift 1.x)

И вот как вы это делаете на Swift (на случай, если вы столкнулись с той же проблемой, что и я)

Ссылка на AudioToolbox.framework (AudioToolbox.framework в свой проект, выберите цель, фазы сборки, AudioToolbox.framework с библиотеками, добавьте туда библиотеку)

Как только это будет завершено:

import AudioToolbox.AudioServices

// Use either of these
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))

SystemSoundID вещь в том, что SystemSoundID - это в основном typealias (fancy swift typedef) для UInt32, а kSystemSoundID_Vibrate - это обычный Int. Компилятор выдает ошибку при попытке преобразования из Int в UInt32, но эта ошибка читается как "Невозможно преобразовать в SystemSoundID", что сбивает с толку. Почему яблоко просто не сделало его быстрым перечислением вне меня.

@aponomarenko углубляется в детали, мой ответ только для Swifters.

Ответ 3

Простой способ сделать это с помощью Audio Services:

#import <AudioToolbox/AudioToolbox.h> 
...    
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

Ответ 4

У меня были большие проблемы с этим для устройств, которые каким-то образом отключили вибрацию, но нам нужно было работать независимо, потому что это важно для работы нашего приложения, и поскольку это всего лишь целое число с запросом на документальный метод, он пройдет проверку. Поэтому я пробовал некоторые звуки, которые были за пределами хорошо документированных здесь: TUNER88/iOSSystemSoundsLibrary

Затем я наткнулся на 1352, который работает независимо от тикового переключателя или настроек на устройстве (Settings->vibrate on ring, vibrate on silent).

- (void)vibratePhone;
{
     if([[UIDevice currentDevice].model isEqualToString:@"iPhone"])
     {
         AudioServicesPlaySystemSound (1352); //works ALWAYS as of this post
     }
     else
     {
          // Not an iPhone, so doesn't have vibrate
          // play the less annoying tick noise or one of your own
          AudioServicesPlayAlertSound (1105);
     }
}

Ответ 5

Важное примечание: Предупреждение о будущих устареваниях.

Как и в iOS 9.0, описание функций API для:

AudioServicesPlaySystemSound(inSystemSoundID: SystemSoundID)
AudioServicesPlayAlertSound(inSystemSoundID: SystemSoundID)

содержит следующее примечание:

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

Правильный способ использования будет использовать любой из этих двух:

AudioServicesPlayAlertSoundWithCompletion(kSystemSoundID_Vibrate, nil)

или

AudioServicesPlayAlertSoundWithCompletion(kSystemSoundID_Vibrate) {
 //your callback code when the vibration is done (it may not vibrate in iPod, but this callback will be always called)
}

помните import AVFoundation

Ответ 6

И если вы используете инфраструктуру Xamarin (monotouch), просто позвоните

SystemSound.Vibrate.PlayAlertSound()

Ответ 7

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

1) AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
2) AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

Мой метод вызывался в определенное время при измерении движений устройств. Я должен был остановить запись, а затем перезапустить ее после того, как произошла вибрация.

Это выглядело так.

-(void)vibrate {
    [recorder stop];
    AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
    [recorder start];
}

recorder - это экземпляр AVRecorder.

Надеюсь, что это поможет другим, у которых была такая же проблема.

Ответ 8

В iOS 10 и на новых iPhone можно также использовать тактильный API. Эта тактильная обратная связь мягче, чем AudioToolbox API.

Для вашего сценария GAME OVER должна подойти сильная обратная связь.

UIImpactFeedbackGenerator(style:.heavy).impactOccurred()

Вы можете использовать другие тактильные стили обратной связи.

Ответ 9

В Swift:

import AVFoundation
...
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))

Ответ 10

Для iPhone 7/7 Plus или новее используйте эти три API-интерфейса обратной связи Haptic.

Доступные API

Для уведомлений:

let generator = UINotificationFeedbackGenerator()
generator.notificationOccured(style: .error)

Доступные стили: .error, .success и .warning. У каждого есть свое отличительное чувство.
Из документов:

Конкретный подкласс UIFeedbackGenerator который создает тактику для сообщения об успехах, сбоях и предупреждениях.

Для простых вибраций:

let generator = UIImpactFeedbackGenerator(style: .medium)
generator.impactOccured()

Доступные стили: .heavy, .medium и .light. Это простые вибрации с различной степенью "твердости".
Из документов:

Конкретный подкласс UIFeedbackGenerator который создает тактику для имитации физических воздействий

Когда пользователь выбрал предмет

let generator = UISelectionFeedbackGenerator()
generator.selectionChanged()

Это наименее заметный из всех тактильных ощущений, и поэтому он наиболее подходит для случаев, когда тактильные ощущения не должны воспринимать опыт приложения.
Из документов:

Конкретный подкласс UIFeedbackGenerator который создает UIFeedbackGenerator, чтобы указать на изменение в выборе.

Заметки

Есть несколько вещей, которые стоит запомнить при использовании этих API.

Примечание А

Вы на самом деле не создаете тактильную. Вы запрашиваете систему генерировать тактильный. Система примет решение на основе ниже:

  • Если на устройстве возможны тактильные ощущения (есть ли в данном случае устройство Taptic Engine)
  • Может ли приложение записывать звук (тактильные сигналы не генерируются во время записи, чтобы предотвратить нежелательные помехи)
  • Включены ли тактильные параметры в настройках системы.

Поэтому система будет молчаливо игнорировать ваш запрос о тактильном, если это невозможно. Если это связано с неподдерживаемым устройством, вы можете попробовать это:

func haptic() {
    // Get whether the device can generate haptics or not
    // If feedbackSupportLevel is nil, will assign 0
    let feedbackSupportLevel = UIDevice.current.value(forKey: "_feedbackSupportLevel") as? Int ?? 0

    switch feedbackSupportLevel { 
    case 2:
        // 2 means the device has a Taptic Engine
        // Put Taptic Engine code here, using the APIs explained above

    case 1: 
    // 1 means no Taptic Engine, but will support AudioToolbox
    // AudioToolbox code from the myriad of other answers!

    default: // 0
        // No haptic support
        // Do something else, like a beeping noise or LED flash instead of haptics
    }

Замените комментарии в операторах switch case, и этот тактильный код генерации будет переносимым на другие устройства iOS. Это создаст самый высокий уровень тактильной возможной.

Примечание Б

  • Из-за того, что генерация тактильных файлов является задачей аппаратного уровня, может возникнуть задержка между тем, когда вы вызываете код генерации тактильного кода, и тем, когда это действительно происходит. По этой причине все API-интерфейсы Taptic Engine имеют метод prepare(), чтобы перевести его в состояние готовности. Используя пример Game Over: вы можете знать, что игра заканчивается, потому что у пользователя очень низкий уровень здоровья или рядом с ними опасный монстр.
  • Если вы не генерируете тактильный сигнал в течение нескольких секунд, Taptic Engine вернется в состояние ожидания (для экономии заряда аккумулятора)


В этом случае подготовка Taptic Engine создаст более качественный и более отзывчивый опыт.

Например, допустим, ваше приложение использует распознаватель панорамирования для изменения видимой части мира. Вы хотите, чтобы тактильный генератор генерировался, когда пользователь "смотрит" вокруг 360 градусов. Вот как вы можете использовать prepare():

@IBAction func userChangedViewablePortionOfWorld(_ gesture: UIPanGestureRecogniser!) {

    haptic = UIImpactFeedbackGenerator(style: .heavy)

    switch gesture.state {
        case .began:
            // The user started dragging the screen.
            haptic.prepare()

        case .changed:
            // The user trying to 'look' in another direction
            // Code to change viewable portion of the virtual world

            if virtualWorldViewpointDegreeMiddle = 360.0 { 
                haptic.impactOccured()
            }

        default:
            break

} 

Ответ 11

В моем случае я использовал AVCaptureSession. AudioToolbox находился на этапах сборки проекта, и он был импортирован, но все еще не работал. Чтобы заставить его работать, я прекратил сеанс перед вибрацией и продолжал после этого.

#import <AudioToolbox/AudioToolbox.h>
...
@property (nonatomic) AVCaptureSession *session;
...
- (void)vibratePhone;
{
  [self.session stopRunning];
     NSLog(@"vibratePhone %@",@"here");
    if([[UIDevice currentDevice].model isEqualToString:@"iPhone"])
    {
        AudioServicesPlaySystemSound (kSystemSoundID_Vibrate); 
    }
    else
    {
        AudioServicesPlayAlertSound (kSystemSoundID_Vibrate);
    }
  [self.session startRunning];
}

Ответ 12

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

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

Теперь вы можете просто позвонить по мере необходимости.

UIDevice.vibrate()

Ответ 13

импортировать AudioToolbox.AudioServices

AudioServicesPlaySystemSound (kSystemSoundID_Vibrate) AudioServicesPlayAlertSound (kSystemSoundID_Vibrate)

Ответ 14

Вы можете использовать

1) AudioServicesPlayAlertSound (kSystemSoundID_Vibrate);

для iPhone и несколько новых iPod.

2) AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);

для iPads.