Are there APIs for custom vibrations in iOS?

After serval hours’ digging in the Contact App, I have figured out how it works.

ABNewPersonViewControlle invoke some class in ToneLibrary framework to do this.

The call stack looks like this:

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

After search “AudioServicesPlaySystemSoundWithVibration” on the web , I found nothing.

So I decide to look into it myself. It’s a private function in AudioToolbox framework.

the declaration of the function is like

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

“inSystemSoundID” is SystemSoundID .just like “AudioServicesPlaySystemSound”, pass “kSystemSoundID_Vibrate”.

“arg” is not important, pass nil to it , everything will still work fine.

“vibratePattern” is a pointer of “NSDictionary”, the Contact App pass into
{
Intensity = 1;
OffDuration = 1;
OnDuration = 10;
} for recording user input.

But only call this function will make a vibration never stop. So I have to found some function to stop it.

The answer is “AudioServicesStopSystemSound”. It’s also a private function in AudioToolbox framework.

the declaration of the function is like

void AudioServicesStopSystemSound(SystemSoundID inSystemSoundID)

I guess the Contact App use AudioServicesPlaySystemSoundWithVibration in touchesBegan method, and AudioServicesStopSystemSound in touchEnd method to reach this effect.

TLVibrationController will manager a vibrate pattern object to record the process you input.

At last it generate a dictionary to pass into AudioServicesPlaySystemSoundWithVibration to replay the whole process like below:

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

So if you want a custom vibrations in iOS. Use AudioServicesPlaySystemSoundWithVibration and AudioServicesStopSystemSound.

Leave a Comment