Gibt es APIs für benutzerdefinierte Vibrationen in iOS?

72

Ab iOS 5 können Benutzer benutzerdefinierte Vibrationsmuster für Warnungen und Ringe erstellen. Der folgende Screenshot zeigt die Benutzeroberfläche zum Erstellen einer (Kontakte-App in iOS 6):

Screenshot der Benutzeroberfläche zum Erstellen benutzerdefinierter Vibrationen in iOS 6

Ich habe mich umgesehen, einschließlich der Dokumentation, und ich kann keine öffentlichen APIs finden, die die Erstellung oder Wiedergabe von benutzerdefinierten Vibrationen verfügbar machen. Am nächsten kommt es, mit dem AudioToolboxFramework eine kurze, konstante Vibration zu spielen:

AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

Weiß jemand, ob es APIs für benutzerdefinierte Vibrationen gibt? Es müssen nicht unbedingt öffentliche APIs sein. Ich bin gespannt, was die Kontakte-App verwendet. Weiß jemand?

PS Andere haben _CTServerConnectionCreatein CoreTelephony( Beispiel ) vorgeschlagen. Ich habe es versucht, konnte aber aus irgendeinem Grund keine Vibration in Gang bringen.

Oktober 2015 Update:

In iOS 9 gibt es neue private APIs für die Interaktion mit der Taptic Engine auf kompatiblen Geräten. Weitere Informationen finden Sie unter Taptic in iOS 9 .

Andrew
quelle
1
Core Haptics kommt in iOS 13! Es ist derzeit in der Beta. Siehe „Erstellen von benutzerdefinierter Haptic Patterns“ hier für weitere Informationen.
Friedenstyp

Antworten:

105

Nach mehreren Stunden in der Kontakt-App habe ich herausgefunden, wie es funktioniert.

ABNewPersonViewControlle ruft dazu eine Klasse im ToneLibrary-Framework auf.

Der Aufrufstapel sieht folgendermaßen aus:

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

Nach der Suche nach "AudioServicesPlaySystemSoundWithVibration" im Web habe ich nichts gefunden.

Also entscheide ich mich, es selbst zu untersuchen. Es ist eine private Funktion im AudioToolbox-Framework.

Die Deklaration der Funktion ist wie

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

"inSystemSoundID" ist SystemSoundID. Übergeben Sie genau wie "AudioServicesPlaySystemSound" "kSystemSoundID_Vibrate".

"arg" ist nicht wichtig, gib nichts an, alles wird noch gut funktionieren.

"vibratePattern" ist ein Zeiger auf "NSDictionary", die Contact App geht in {Intensity = 1; OffDuration = 1; OnDuration = 10; } zum Aufzeichnen von Benutzereingaben.

Wenn Sie diese Funktion nur aufrufen, hört eine Vibration niemals auf. Also muss ich eine Funktion finden, um es zu stoppen.

Die Antwort lautet "AudioServicesStopSystemSound". Es ist auch eine private Funktion im AudioToolbox-Framework.

Die Deklaration der Funktion ist wie

void AudioServicesStopSystemSound(SystemSoundID inSystemSoundID)

Ich denke, die Kontakt-App verwendet AudioServicesPlaySystemSoundWithVibration in der touchBegan-Methode und AudioServicesStopSystemSound in der touchEnd-Methode, um diesen Effekt zu erzielen.

TLVibrationController verwaltet ein Vibrationsmusterobjekt, um den von Ihnen eingegebenen Prozess aufzuzeichnen.

Zuletzt wird ein Wörterbuch generiert, das an AudioServicesPlaySystemSoundWithVibration übergeben wird, um den gesamten Prozess wie folgt abzuspielen:

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);

Also, wenn Sie eine benutzerdefinierte Vibration in iOS wollen. Verwenden Sie AudioServicesPlaySystemSoundWithVibration und AudioServicesStopSystemSound.

Kevin Cao
quelle
5
Hinweis: AudioServicesPlaySystemSoundWithVibration ist nur unter iOS6 verfügbar.
Kevin Cao
2
@Jonny FOUNDATION_EXTERN "AudioServicesPlaySystemSoundWithVibration (unsigned long, objc_object *, NSDictionary *) wird den Trick machen. Vergessen Sie nicht, auch gegen AudioToolbox.framework
JonasG
9
Jetzt lehnt Apple AudioServicesPlaySystemSoundWithVibration beim Senden ab.
Max Tymchii
3
Gibt es eine Möglichkeit, eine benutzerdefinierte Vibration zu implementieren, ohne dass die App von Apple abgelehnt wird?
Bobsacameno
2
Dadurch erhalten Sie nur eine nette E-Mail wie folgt: ** Wir haben ein oder mehrere Probleme mit Ihrer letzten Zustellung für "Appname" festgestellt. Um Ihre Lieferung zu verarbeiten, müssen die folgenden Probleme behoben werden: Nicht öffentliche API-Verwendung: Die App verweist auf nicht öffentliche Symbole in Appname: _AudioServicesPlaySystemSoundWithVibration **
Edoardo
4

Es gibt ein Projekt namens HapticKeyboard, das dies tut. Siehe: http://code.google.com/p/zataangstuff/source/browse/trunk/HapticKeyboard/Classes/HapticKeyboard.m?r=93

Schauen Sie sich insbesondere die letzten Funktionen an

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

Es gibt zwei Probleme:

  1. Ich bezweifle, dass Sie Ihre App in den App Store bekommen würden. Apple wird dies als Batterieentladung für Benutzer ansehen und sie sind ziemlich streng in Bezug auf die Benutzererfahrung
  2. Dies kann Jailbreaking erfordern. Seit ich das letzte Mal damit gespielt habe, gab es mehrere neue iOS-Versionen, daher ist es schwer zu sagen
Jonathan
quelle
Danke für deine Antwort. Ich habe mir HapticKeyboard (das 4 Jahre alt ist) bereits angesehen, bevor ich meine Frage gestellt habe. Ich habe versucht, Vibrationen wie im Code beschrieben auszulösen, aber es hat bei mir nicht funktioniert. Ich suche nach APIs, mit denen Apple benutzerdefinierte Vibrationen in Kontakten implementiert, wie im Screenshot gezeigt.
Andrew
1
Apples HapticEngine und alle Vibrationsreaktionen auf anderen Geräten sind tatsächlich ein Batterieverbrauch. Übrigens ist die Codeverbindung unterbrochen.
Kelin