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

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

Снимок экрана пользовательского интерфейса для создания пользовательских вибраций в iOS 6

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

AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

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

PS другие предложили _CTServerConnectionCreate в CoreTelephony ( пример). Я попробовал, но по какой-то причине вибрация не пошла.

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

В iOS 9 появились новые частные API для взаимодействия с Taptic Engine на совместимых устройствах. См. Taptic в iOS 9 для получения дополнительной информации.

2 ответа

Решение

После рытья сервал часов в приложении 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", приложение Contact передается в { Intensity = 1; OffDuration = 1; OnDuration = 10; } для записи пользовательского ввода.

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

Ответ - "AudioServicesStopSystemSound". Это также частная функция в платформе AudioToolbox.

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

void AudioServicesStopSystemSound(SystemSoundID inSystemSoundID)

Я предполагаю, что приложение Contact использует AudioServicesPlaySystemSoundWithVibration в методе touchesBegan и 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.

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

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

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

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

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