web-dev-qa-db-fra.com

Faire vibrer l'iPhone

Comment configurer l'iPhone pour qu'il vibre une fois?

Par exemple, lorsqu'un joueur perd une vie ou que le jeu est terminé, l'iPhone devrait vibrer.

225
jarryd

De " Tutoriel iPhone: Meilleur moyen de vérifier les capacités des appareils iOS ":

Deux fonctions apparemment similaires prennent un paramètre kSystemSoundID_Vibrate:

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

Les deux fonctions font vibrer l'iPhone. Cependant, lorsque vous utilisez la première fonction sur des appareils non compatibles avec les vibrations, un bip retentit. La deuxième fonction, en revanche, ne fait rien sur les appareils non pris en charge. Par conséquent, si vous voulez faire vibrer l'appareil en permanence, utilisez la fonction 2, indique le bon sens.

Tout d’abord, ajoutez le cadre AudioToolbox AudioToolbox.framework à votre cible dans Build Phases.

Ensuite, importez ce fichier d'en-tête:

#import <AudioToolbox/AudioServices.h>
400
linuxbuild

Swift 2.0+

AudioToolbox présente maintenant le kSystemSoundID_Vibrate comme un type SystemSoundID. Le code est donc:

import AudioToolbox.AudioServices

AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)

Au lieu d'avoir à passer par l'étape de casting supplémentaire

(Accessoires à @Dov)

Réponse originale (Swift 1.x)

Et voici comment vous le faites sur Swift (au cas où vous auriez le même problème que moi)

Lien contre AudioToolbox.framework (Allez à votre projet, sélectionnez votre cible, phases de construction, Lien binaire avec les bibliothèques, ajoutez la bibliothèque là-bas)

Une fois cela terminé:

import AudioToolbox.AudioServices

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

La chose ringarde est que SystemSoundID est fondamentalement un typealias (fantaisie Swift typedef) pour un UInt32, et le kSystemSoundID_Vibrate est un régulier Int. Le compilateur vous donne une erreur lorsque vous tentez de transtyper de Int à UInt32, mais l’erreur indique "Impossible de convertir en SystemSoundID", ce qui prête à confusion. Pourquoi Apple n'a-t-il pas simplement fait en Swift une énumération qui me dépasse?.

@ aponomarenko's va dans les détails, ma réponse est juste pour les Swifters là-bas.

45
Can

Un moyen simple de le faire est d'utiliser Audio Services:

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

Cela me posait de gros problèmes pour les périphériques dont les vibrations avaient été désactivées, mais nous devions le faire fonctionner de manière indépendante, car il est essentiel au fonctionnement de notre application et, comme il ne s'agit que d'un entier à un appel de méthode documenté, il passera. validation. J'ai donc essayé quelques sons qui étaient en dehors de ceux bien documentés ici: TUNER88/iOSSystemSoundsLibrary

Je suis ensuite tombé sur 1352, qui fonctionne indépendamment du commutateur silencieux ou des paramètres du périphérique (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);
     }
}
28
Joel Teply

Note importante: Alerte de dépréciation future.

À partir de iOS 9., la description des fonctions API pour:

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

comprend la note suivante:

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

La bonne façon d’utiliser l’une de ces deux méthodes est la suivante:

AudioServicesPlayAlertSoundWithCompletion(kSystemSoundID_Vibrate, nil)

ou

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

souvenez-vous de import AVFoundation

24
Hugo Alonso

Et si vous utilisez le framework Xamarin (monotouch), appelez simplement

SystemSound.Vibrate.PlayAlertSound()
5
Wheelie

Au cours de mes voyages, j'ai constaté que si vous essayez l'une des opérations suivantes pendant l'enregistrement audio, l'appareil ne vibre pas, même s'il est activé.

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

Ma méthode a été appelée à un moment précis dans la mesure des mouvements des appareils. Je devais arrêter l'enregistrement puis le redémarrer après que la vibration se soit produite.

Cela ressemblait à ceci.

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

recorder est une instance d'AVRecorder.

J'espère que cela aide d'autres personnes qui ont déjà eu le même problème.

5
Sebastien Peek

Dans iOS 10 et sur les nouveaux iPhones, vous pouvez également utiliser l'API haptique. Ce retour haptique est plus doux que l'API AudioToolbox.

Pour votre scénario GAME OVER, un retour d’impact important de l’UI devrait convenir.

UIImpactFeedbackGenerator(style: .heavy).impactOccurred()

Vous pouvez utiliser le autres styles de retour haptique .

4
samwize

Pour un iPhone 7/7 Plus ou plus récent, utilisez ces trois API de retour d'informations Haptic.

API disponibles

Pour les notifications:

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

Les styles disponibles sont .error, .success et .warning. Chacun a sa propre sensation distinctive.
Du docs :

Une sous-classe UIFeedbackGenerator concrète qui crée une haptique pour communiquer les succès, les échecs et les avertissements.

Pour des vibrations simples:

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

Les styles disponibles sont .heavy, .medium et .light. Ce sont de simples vibrations avec différents degrés de "dureté".
Du docs :

Une sous-classe UIFeedbackGenerator concrète qui crée une haptique pour simuler des impacts physiques

Pour quand l'utilisateur a sélectionné un élément

let generator = UISelectionFeedbackGenerator()
generator.selectionChanged()

C’est le moins perceptible de tous les haptiques, et donc le plus approprié lorsque l’haptique ne devrait pas s’approprier l’expérience de l’application.
Du docs :

Une sous-classe UIFeedbackGenerator concrète qui crée une haptique pour indiquer un changement de sélection.

Remarques

Lorsque vous utilisez ces API, il convient de garder à l’esprit certaines choses qu’il convient de retenir.

Pas de thé

Vous ne créez pas réellement l'haptique. Vous demandez au système de générer un haptique. Le système décidera en fonction de ce qui suit:

  • Si l'haptique est possible sur l'appareil (si ce dernier dispose d'un Taptic Engine)
  • Si l'application peut enregistrer de l'audio (les haptiques ne sont pas générés pendant l'enregistrement pour éviter les interférences indésirables)
  • Si les haptiques sont activés dans les paramètres système.

Par conséquent, le système ignorera votre demande silencieuse si cela n’est pas possible. Si cela est dû à un périphérique non pris en charge, vous pouvez essayer ceci:

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
    }

Remplacez les commentaires dans les instructions switch-case et ce code de génération haptique sera portable sur d'autres appareils iOS. Cela générera le plus haut niveau possible d'haptique.

Note b

  • Du fait que la génération d’haptiques est une tâche de niveau matérielle , il peut y avoir une latence entre le moment où vous appelez la génération haptique code, et quand cela se produit . Pour cette raison, les API Taptic Engine ont toutes une méthode prepare() pour le mettre en état de disponibilité. Exemple d'utilisation de Game Over: Vous savez peut-être que le jeu est sur le point de se terminer, l'utilisateur ayant très peu de HP, ou un monstre dangereux se trouvant à proximité.
  • Si vous ne générez pas d'alerte au bout de quelques secondes, le Taptic Engine repasse à l'état inactif (pour économiser la durée de vie de la batterie).


Dans ce cas, préparer le moteur Taptic créerait une expérience de meilleure qualité et plus réactive.

Par exemple, supposons que votre application utilise un outil de reconnaissance des gestes panoramiques pour changer la partie du monde visible. Vous souhaitez générer un haptique lorsque l'utilisateur "regarde" à 360 degrés. Voici comment utiliser 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

} 
3
Benj

En rapide:

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

Dans mon cas, j'utilisais AVCaptureSession. AudioToolbox était en phase de construction du projet et il a été importé mais ne fonctionnait toujours pas. Pour que cela fonctionne, j'ai arrêté la session avant vibration et continué après cela.

#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];
}
0
Caner Çakmak