71 votes

Existe-t-il des API pour les vibrations personnalisées dans iOS ?

À partir d'iOS 5, les utilisateurs peuvent créer des modèles de vibration personnalisés pour les alertes et les sonneries. La capture d'écran suivante montre l'interface utilisateur permettant d'en créer un (application Contacts dans iOS 6) :

Screenshot of UI for creating custom vibrations in iOS 6

J'ai cherché partout, y compris dans la documentation, et je ne trouve aucune API publique permettant de créer ou de lire des vibrations personnalisées. La solution la plus proche est d'utiliser la fonction AudioToolbox cadre pour jouer une vibration courte et constante :

AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

Quelqu'un sait-il s'il existe des API pour les vibrations personnalisées ? Il ne s'agit pas nécessairement d'API publiques. Je suis curieux de savoir ce que l'application Contacts utilise. Est-ce que quelqu'un le sait ?

_P.S. D'autres ont suggéré _CTServerConnectionCreate en CoreTelephony ( exemple ). J'ai essayé, mais je n'ai pas réussi à obtenir de vibration pour une raison quelconque._

Mise à jour d'octobre 2015 :

Il existe de nouvelles API privées dans iOS 9 pour interagir avec le Taptic Engine dans les appareils compatibles. Voir Taptic dans iOS 9 pour plus.

102voto

Kevin Cao Points 879

Après avoir passé plusieurs heures à creuser dans l'application Contact, j'ai compris comment cela fonctionne.

ABNewPersonViewControlle invoque une classe dans le cadre de ToneLibrary pour faire cela.

La pile d'appels ressemble à ceci :

0   CoreFoundation                  0x3359a1d4 CFGetTypeID + 0
1   CoreFoundation                  0x33596396 __CFPropertyListIsValidAux + 46
2   CoreFoundation                  0x33517090 CFPropertyListCreateData + 124
3   AudioToolbox                    0x38ac255a AudioServicesPlaySystemSoundWithVibration + 158
5   ToneLibrary                     0x35a7811a -[TLVibrationRecorderView vibrationComponentDidStartForVibrationRecorderTouchSurface:] + 38
6   ToneLibrary                     0x35a772b2 -[TLVibrationRecorderTouchSurface touchesBegan:withEvent:] + 342
7   UIKit                           0x3610f526 -[UIWindow _sendTouchesForEvent:] + 314
8   UIKit                           0x360fc804 -[UIApplication sendEvent:] + 376

Après avoir cherché "AudioServicesPlaySystemSoundWithVibration" sur le web, je n'ai rien trouvé.

Je décide donc de me renseigner moi-même. C'est une fonction privée dans le framework AudioToolbox.

la déclaration de la fonction est la suivante

void AudioServicesPlaySystemSoundWithVibration(SystemSoundID inSystemSoundID,id arg,NSDictionary* vibratePattern)

"inSystemSoundID" est SystemSoundID .tout comme "AudioServicesPlaySystemSound", passe "kSystemSoundID_Vibrate".

"arg" n'est pas important, passez-lui nil, tout fonctionnera encore correctement.

"vibratePattern" est un pointeur de "NSDictionary", le Contact App passe dans { Intensité = 1 ; OffDuration = 1 ; OnDuration = 10 ; } pour enregistrer les entrées de l'utilisateur.

Mais seul l'appel de cette fonction fera qu'une vibration ne s'arrêtera jamais. Je dois donc trouver une fonction pour l'arrêter.

La réponse est "AudioServicesStopSystemSound". Il s'agit également d'une fonction privée dans le cadre de l'AudioToolbox.

la déclaration de la fonction est la suivante

void AudioServicesStopSystemSound(SystemSoundID inSystemSoundID)

Je suppose que l'application Contact utilise AudioServicesPlaySystemSoundWithVibration dans la méthode touchBegan, et AudioServicesStopSystemSound dans la méthode touchEnd pour obtenir cet effet.

TLVibrationController gérera un objet de modèle de vibration pour enregistrer le processus que vous avez entré.

Enfin, il génère un dictionnaire à passer à AudioServicesPlaySystemSoundWithVibration pour rejouer tout le processus comme ci-dessous :

NSMutableDictionary* dict = [NSMutableDictionary dictionary];
NSMutableArray* arr = [NSMutableArray array ];

[arr addObject:[NSNumber numberWithBool:YES]]; //vibrate for 2000ms
[arr addObject:[NSNumber numberWithInt:2000]];

[arr addObject:[NSNumber numberWithBool:NO]];  //stop for 1000ms
[arr addObject:[NSNumber numberWithInt:1000]];

[arr addObject:[NSNumber numberWithBool:YES]];  //vibrate for 1000ms
[arr addObject:[NSNumber numberWithInt:1000]];

[arr addObject:[NSNumber numberWithBool:NO]];    //stop for 500ms
[arr addObject:[NSNumber numberWithInt:500]];

[dict setObject:arr forKey:@"VibePattern"];
[dict setObject:[NSNumber numberWithInt:1] forKey:@"Intensity"];

AudioServicesPlaySystemSoundWithVibration(4095,nil,dict);

Donc si vous voulez une vibration personnalisée dans iOS. Utilisez AudioServicesPlaySystemSoundWithVibration et AudioServicesStopSystemSound.

4voto

Jonathan Points 749

Il y a un projet appelé HapticKeyboard qui fait cela. Voir : http://code.google.com/p/zataangstuff/source/browse/trunk/HapticKeyboard/Classes/HapticKeyboard.m?r=93

Plus précisément, regardez le dernier ensemble de fonctions

_CTServerConnectionSetVibratorState(&x, connection, 0, 0, 0, 0, 0);

Il y a deux problèmes :

  1. Je doute que votre application soit autorisée dans le magasin d'applications. Apple verra cela comme un épuisement de la batterie pour les utilisateurs et ils sont assez stricts sur l'expérience utilisateur.
  2. Cela peut nécessiter un jailbreak. Il y a eu plusieurs nouvelles versions d'iOS depuis la dernière fois que j'ai joué avec ça, donc c'est difficile à dire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X