I am trying to perform a vibration in an app similar to Snapchat, that uses both audio output and input as well as supports audio mixing from other apps, but this seems to be a harder task that I initially thought it would be. Important to know is that I am not trying to vibrate during playback or recording. From reading all the documentation I could find on the subject, this is what I have come to understand:
- In order to support both playback and recording (output and input), I need to use
AVAudioSessionCategoryPlayAndRecord
- Making the phone vibrate through
AudioServicesPlaySystemSound (kSystemSoundID_Vibrate)
is not supported in any of the recording categories, includingAVAudioSessionCategoryPlayAndRecord
. - Enabling other apps to play audio can be done by adding the option
AVAudioSessionCategoryOptionMixWithOthers
.
Therefore, I do this in my app delegate:
NSError *error = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionMixWithOthers error:&error];
The possible solutions to doing the vibration that I have tried but failed at are:
Deactivating the shared
AVAudioSession
before vibrating, and then activate it straight after.[[AVAudioSession sharedInstance] setActive:NO error:nil]; AudioServicesPlaySystemSound (kSystemSoundID_Vibrate); [[AVAudioSession sharedInstance] setActive:YES error:nil];
This successfully performs the vibration, but afterwards, when I try to record a movie, the audio is ducked (or something else is causing it to be very silent). It also gives me an error saying that I am not allowed to deactivate a session without removing its I/O devices first.
Changing category before vibrating, and then changing it back.
[[AVAudioSession sharedInstance] setActive:NO error:nil]; [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil]; [[AVAudioSession sharedInstance] setActive:YES error:nil]; AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); [[AVAudioSession sharedInstance] setActive:NO error:nil]; [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionMixWithOthers error:nil]; [[AVAudioSession sharedInstance] setActive:YES error:nil];
This solution comes up every now and then, but does not seem to work for me. No vibration occurs, even though the categories seems to be set. This might still be a valid solution if I set
usesApplicationAudioSession = YES
on my AVCaptureSession, but I haven't made it work yet.
Sources: