change output speaker when user move his phone - ios

My app lets the user hear sound files, and im using AVAudioPlayer to play it.
I saw in some apps a very nice behaviour where the sound speakers changes from regular speakers to the ear speakers when the user put his phone next to his ear.
I have now idea where to start here, should i detect the phone's movement and change the output speaker or is there any native implementation for this behaviour?

The most straightforward path to accomplishing this is to use proximity monitoring in UIDevice. Proximity monitoring tells you whether the phone is close to the user or not.
Listen for UIDeviceOrientationDidChangeNotification and react to proximityState changes accordingly — in your case, rerouting audio.
There's a thorough answer to a similar question here. That answer includes supplementary details to combine device motion for increased accuracy.

What you're looking for is the proximity sensor (that little piece of hardware near the iphone ear speaker), and not any motion sensing mechanism. The proximity sensor is accessible via the public API through the UIDevice's proximityState property, which simply returns a boolean value indicating whether the sensor is close to the user or not: proximityState.
Based on that value, you can then proceed to routing your audio to the ear speaker. This can be achieved using the AVAudioSession class and specifically setting the category (setCategory:error) to AVAudioSessionCategoryPlayAndRecord.

Related

Can I find out whether the user is driving?

I am writing an app for iOS.
I want to know the user's current motion type, for example, walking, driving running. In particular I am interested in knowing whether they are driving.
I would also like to detect when the device connects to a car Bluetooth, as this may also indicate that they are driving.
While your app is active you can use CMMotionActivityManager to get the current motion type.
Note that it won't tell you whether the person is driving or a passenger or even in another vehicle that has similar motion characteristics, such as a train. You can't get motion activity updates while your app is suspended.
You could combine it with Signification Location updates to get periodic execution in the background.
This answer has some suggestions on detecting Bluetooth HFP devices by checking the available audio input devices. Note that you can't check this in the background and you can't get a "notification" that a HFP has connected unless you are actively inputting or outputting audio - You would need to check periodically

iOS 10 Speech to text Framework integration : How to know user stop talking

We are following blog present on below URL to integrate Speech Kit framework in our application
https://www.appcoda.com/siri-speech-framework/
This sample is working fine.
But can anyone know How to detect user has stop talking?. As the audio session is stop after 1 min. But we want to detect if user has completed talking so that we can identify any specific word user has said. And after completion of this we can again start the audio session.
Thanks in Advance!!!!
There is no option in Speech framework by which you can detect user has stop talking. But there is a way around. You have to detect ambient sound level in decibel. Also you have to run a timer. Now after certain time say ~5 seconds if you are not receiving any sound or the decibel level becomes very low, you have to stop the microphone. Please note that the decibel level will never become ZERO as there is always some noise in our surroundings. So you have to calculate the level.
Here is the link where you can calculate the sound level in decibel -
http://www.b2cloud.com.au/tutorial/obtaining-decibels-from-the-ios-microphone/

Reroute Audio to Bluetooth Speaker

I am creating a Video & Audio capturing app. Every time I start to record, the music played in the bluetooth speaker plays in the phone's speaker. When I exit the app, the music comes back playing on the bluetooth speaker.
My first attempt to solve this is to provide the necessary options for the audioSession, like this:
try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord, withOptions: [AVAudioSessionCategoryOptions.MixWithOthers, AVAudioSessionCategoryOptions.AllowBluetooth])
But that didn't work. So my second solution that I'm thinking is to reroute the music output again to the bluetooth speaker.
I researched on this and found this function: audioSession.setOutputDataSource
I don't really know the parameters to be passed there.
And I am not really sure if in the moment I started the video recording, the phone/or my code disables the bluetooth connection or it just reroutes the playback to the phone's speaker.
UPDATE: I coommented out this line: // try audioSession.setMode(AVAudioSessionModeMoviePlayback) and the music pauses a bit and plays again on the bluetooth speaker. But the problem here is that the captured video has no audio.
UPDATE 2: Would this question have a solution if I provide you with my code?
I'll go ahead and take a shot at answering the original question. From Apple
s documentation I go this:
func setOutputDataSource(_ dataSource: AVAudioSessionDataSourceDescription?)throws
Parameters dataSource
The data source for the audio session’s output.
outError
On input, a pointer to an error object. If an error occurs, the pointer is set to an NSError object that describes the
error. If you do not want error information, pass in nil. here
This page should help you figure out what the AV Session data source description does/returns, but in summery it:
You obtain data source descriptions from the shared AVAudioSession object or the AVAudioSessionPortDescription objects corresponding to its input and output ports. Only built-in microphone ports on certain devices support the location, orientation, and polar pattern properties; if a port does not support these features, the value of its dataSources property is nil. here
Are you trying to route music from your app to the speaker (is that the music playing?) or is the music coming from another app, and you would like a dual output?
For error checking you could make sure the speaker is still available, using something like the output data source. If it returns nill (null.) it means you are not able to switch between data-sources.
It's probably also worth noting the user must give you permission to record, however I doubt this is the problem as you seem to have already been recording at one point, just when it was playing through the phone, not the speaker

How can I capture the accelerometer data on iPhone when the app is in background?

In an iOS app, by enabling the flags for VOIP, Audio playback, Location, Bluetooth LE accessories, News stand etc, we can run the app in background. But I've a requirement to create a library/framework that will make the app run in background as well as capture the accelerometer updates and log them to a file.
For that purpose, I enabled "Audio Playback" in the background, and playing a silent file in continuous loop so that app will continue to run in background. At the same time, I'm able to capture the accelerometer data as well. I'm using Core Motion framework for the same and its working perfect.
I would like to add one more point, my app has location tracking enabled to deal with beacons integration.
I want to know if its valid to follow such procedure and will Apple approve it during the review process? Has any one faced this kind of challenge ever?
As you guessed, the only way to access accelerometer data in background is with an active background mode. But...
Apple will NEVER accept your app if it declares a background mode without any feature actually using it (not just technically like your silent sound, but an actual feature that your user is aware of)
If you decide to implement a feature that actually use a background mode (like location or audio playback for example), don't forget that you will also drain your user's battery.
Conclusion:
Explain to your client that Apple's restrictions prevent you to do that and have the requirements updated
or
Find another feature that will need to use one of the background modes

iOS Audio Playback Over Phone Call

I've found a few related questions for Android but nothing for iOS.
Is there any possible way to override the phone's microphone once a phone call has been received and playback an audio file over the phone call? If it's not possible to override the microphone, is there a way to mix in an audio file along with the microphone?
I don't believe you can do what you're wanting. From Apple's Audio Session Programming Guide:
The system follows the inviolable rule that “the phone always wins.” No app, no matter how vehemently it demands priority, can trump the phone. When a call arrives, the user gets notified and your app is interrupted—no matter what audio operation you have in progress and no matter what category you have set.
Which, if you think about it, makes sense: A user is unlikely to want unexpected audio to interrupt or overlay a phone conversation.

Resources