• 1
Votes
name
name Punditsdkoslkdosdkoskdo

Are there APIs for custom vibrations in iOS?

Starting in iOS 5, users are able to create custom vibration patterns for alerts and rings. The following screenshot shows the UI for creating one (Contacts app in iOS 6):

Screenshot of UI for creating custom vibrations in iOS 6

I've been searching around, including the documentation, and I cannot find any public APIs that expose the creation or playback of custom vibrations. The closest thing is to use the AudioToolboxframework to play a short, constant vibration:

AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

 

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.

  • 0
Reply Report