Существуют ли API для пользовательских вибраций в iOS?

Начиная с iOS 5, пользователи могут создавать собственные шаблоны вибраций для предупреждений и звонков. На следующем скриншоте показан пользовательский интерфейс для создания одного (приложение "Контакты" в iOS 6):

Screenshot of UI for creating custom vibrations in iOS 6

Я искал вокруг, включая документацию, и я не могу найти никаких публичных API, которые раскрывают создание или воспроизведение пользовательских вибраций. Ближе всего использовать фреймворк AudioToolbox для воспроизведения короткой, постоянной вибрации:

AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

Кто-нибудь знает, есть ли API для пользовательских вибраций? Это необязательно должно быть общедоступным API. Мне любопытно узнать, что использует приложение "Контакты". Кто-нибудь знает?

P.S. Другие предложили _CTServerConnectionCreate в CoreTelephony (пример). Я попробовал, но по какой-то причине не мог получить вибрацию.

Октябрь 2015 Обновление:

В iOS 9 есть новые частные API, которые взаимодействуют с Taptic Engine в совместимых устройствах. Подробнее см. Taptic в iOS 9.

Ответ 1

После того, как часы обработки часов в приложении Contact, я выяснил, как это работает.

ABNewPersonViewControlle вызывает в классе ToneLibrary некоторый класс.

Стек вызова выглядит следующим образом:

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

После поиска "AudioServicesPlaySystemSoundWithVibration" в Интернете я ничего не нашел.

Поэтому я решил сам изучить это. Это частная функция в среде AudioToolbox.

объявление функции похоже на

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

"inSystemSoundID" - это SystemSoundID. Просто как "AudioServicesPlaySystemSound", передайте "kSystemSoundID_Vibrate".

"arg" не имеет значения, переходите к нему, все будет работать нормально.

"vibratePattern" - это указатель "NSDictionary", переход в приложение "Контакт"   {   Интенсивность = 1;   OffDuration = 1;   OnDuration = 10;   } для записи пользовательского ввода.

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

Ответ: "AudioServicesStopSystemSound". Это также частная функция в среде AudioToolbox.

объявление функции похоже на

void AudioServicesStopSystemSound(SystemSoundID inSystemSoundID)

Я думаю, что приложение Contact использует AudioServicesPlaySystemSoundWithVibration в методе touchhesBegan и метод AudioServicesStopSystemSound в touchEnd для достижения этого эффекта.

TLVibrationController будет управлять вибрирующим объектом шаблона для записи процесса, который вы вводили.

Наконец, он генерирует словарь для передачи в AudioServicesPlaySystemSoundWithVibration для воспроизведения всего процесса, как показано ниже:

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

Итак, если вам нужны пользовательские вибрации в iOS. Используйте AudioServicesPlaySystemSoundWithVibration и AudioServicesStopSystemSound.

Ответ 2

Здесь выполняется проект под названием HapticKeyboard. См.: http://code.google.com/p/zataangstuff/source/browse/trunk/HapticKeyboard/Classes/HapticKeyboard.m?r=93

В частности, посмотрите на последний набор функций

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

Есть две проблемы:

  • Я сомневаюсь, что вы включили приложение в магазин приложений. Apple увидит это как утечку батареи для пользователей, и они довольно строги относительно пользовательского опыта.
  • Это может потребовать джейлбрейка. Было несколько новых версий iOS с тех пор, как я в последний раз играл с этим, поэтому трудно сказать