stop audio while in background - ios

There is an app called IHeartRadio which lets you set a sleep timer which will shut off audio after a specified interval.
You first choose a station to listen to and then select an amount of time to sleep after which the radio station will stop playing. The app does not need to be in the foreground for this to happen.
How is it possible for an app to stop audio while it is in the background?
One theory was to set a UILocalNotification with silent audio. Then the UILocalNotification would take over the audio of the device, in effect silencing whatever audio was playing. That didn't work.
Timers don't work in the background, which doesn't leave much in terms of time-based behavior in the background.

When the UIBackgroundModes key contains the audio value, the system’s media frameworks automatically prevent the corresponding app from being suspended when it moves to the background. As long as it is playing audio or video content, the app continues to run in the background. However, if the app stops playing the audio or video, the system suspends it.
From iOS App Programming Guide.

You can use applicationDidEnterBackground event in your AppDelegate to handle application going to background and stop audio in this method.
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
// add your audio stopping code ..
}

Related

Watchkit: playHaptic has no effect when executing in an inactive or background application state

I want to play the notification in iWatch in both state background and foreground.
I tried this but this is not working only in the background
DispatchQueue.global().asyncAfter(deadline: .now() + 2.0) {
WKInterfaceDevice().play(.notification)
}
Error
WKInterfaceDevice playHaptic has no effect when executing in an
inactive or background
Also, I read this https://forums.developer.apple.com/thread/52630.
Now the question is this, Is there any way to vibrate the watch in the background and foreground for reminding purpose?
or any other alternate way to achieve this?
Thanks
The documentation clearly states that this is not possible.
This method has no effect when called while your shared
WKExtension object's applicationState property is either background or inactive.
Only workout apps can play Haptic feedback in the background if an active Workout session is running.
If you need don't want to play a Haptic, but only need the vibration, you can send a local notification to the user, which will either play a sound or vibration depending on whether Silent mode is on or off.

Background recording and server upload

I have an iOS app that is communicating with a bluetooth peripheral. When you tap a button on the peripheral, the app should start recording, whether it's in background or foreground.
Furthermore, there will be multiple recordings, in order to send them quickly to the server. So the app will record in chunks and then send them to the Parse database that I set up.
The chunk recording and uploading parts are working fine, but I have problems while the whole process starts in background, due to the bluetooth notification. The code that starts the recording is executed, but the completion block of the upload process is not. Maybe the recording starts but never finishes because the system stops the execution, since the app is in background?
I added the audio background mode so the app will be able to record in background, and I also added the voip background mode, since I read it will enable background network activity (which is something that I need in this case).
Unfortunately this didn't work.
Any suggestions will be appreciated.

Keep app running while iOS device locked?

I have an app that makes heavy use of video out. In a typical use-case, I'll have an iPad connected to an external monitor. I just want the external monitor on; the iPad display does not need to stay on.
The ideal case would be for someone to connect to an external monitor, then lock their iPad. But that pauses my app. (Currently, I'm calling setIdleTimerDisabled to keep the iPad from locking up and pausing my app.)
I'd like to give the user the option of locking the iPad, but still having my app running and sending images to video out. (Note: I'm not talking about keeping my app running when it's not in the foreground. I just want to keep it running while it's in the foreground, but the device is locked.)
Is this possible?
I would say no, it is not possible. Here's why:
The docs read:
Pressing the Sleep/Wake button is another type of interruption that causes your app to be deactivated temporarily. When the user presses this button, the system disables touch events, moves the app to the background but sets the value of the app’s applicationState property to UIApplicationStateInactive (as opposed to UIApplicationStateBackground), and finally locks the screen.
Something interesting to note in the docs above is that a bit further down under "What to do when an interruption occurs" Apple recommends that you stop doing certain tasks.
In response to this change, your app should do the following in its applicationWillResignActive: method:
Stop timers and other periodic tasks.
Stop any running metadata queries.
Do not initiate any new tasks.
Pause movie playback (except when playing back over AirPlay).
Enter into a pause state if your app is a game.
Throttle back OpenGL ES frame rates.
Suspend any dispatch queues or operation queues executing non-critical code. (You can continue processing network requests and other time-sensitive background tasks while inactive.)
This tells me that Apple doesn't want or expect your app to be doing much of anything in this state, other than preparing to be fully backgrounded.
On a related note here's a thread that shows how to determine whether you've hit the Sleep/Wake button or not:
Is it possible to distinguish between locking the device and sending an app to background?

UILocalNotification how to call certain method if application is in background

I am creating player application, which is playing audio streams through internet. I want to add alarm functionality in my app - in particular time my player begins to play audio stream, I am trying to use UILocalNotification mechanism. But I've difficulties with it when my application in background mode, I can't call 'play' method, when notification is receiced (can't without user interaction). May be it is impossible?
But I bought this application:
http://itunes.apple.com/us/app/radio-alarm-clock-mp3-radio/id380271167?mt=8
And it seems like radio can start playing when local notification is received. Alarm can start playing radio when my app is in background mode.
Earlier I was trying to use NSTimer for this, but when my app goes to background, timer stops. If I use beginBackgroundTaskWithExpirationHandler: it works only 10 minutes. My app has special flag in plist, what is is audio application, and can playing music in background. In this case timers are working. But if I stop playing and go to background, timer is not working.
When I use \Radio Alarm Clock' application, I hear 'white noise' from dinamic, when music in not playing. May be it is the secret of this application?
Can you help me with my problem? Thanks.
maybe it's too late.
I had a look to the app you've mentioned at http://itunes.apple.com/us/app/radio-alarm-clock-mp3-radio/id380271167?mt=8 and yes, I think you are absolutely right, the only way to achieve that the application remains active while in background is to play a fake sound while it is in the background, which should be prohibited by Apple.
I've also seen that they don't use the remote iPod control, and this was strange at a first look.
At the end my opinion is that they do the following:
Avoid the call to beginReceivingRemoteControlEvents which allows to activate the iPod controls while in background (in fact they don't have it)
In this way, the status bar doesn't show the play icon while
the app plays audio
When the app goes in background, it probably plays a no sound periodically (once every 10 secs for example), in this way the app remains active
I saw that they also avoided to manage interruptions, for example in case another app is in foreground and plays music. Again Apple should have rejected the app for that reason, cos it is against the rules to follow while in background, but maybe they didn't see it during the acceptance tests.
So my interpretation is that they have intentionally missed to activate the iPod controls, just to avoid to show the play icon in the status bar while in background. In this way, the users are unaware that the app is active and is doing something strange after they close it.
In addition you can see that the app doesn't interrupt when another app plays in foreground a sound or audio, because otherwise they risk that the app doesn't restart on time when the alarm shpould fire.
That's just my idea of how they do that, and I think this is the only way for an audio app on iOS to remain active while it is in background and is supposed to be halted (well, in case Apple doesn't see the trick).
Have you tried adding this to appdelegate.m
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
// Call your method in here.
}
if you have can you add code for us to see what your doing.

How to pause/resume audio when iphone is locked/unlocked

Here's what currently happens in my app:
Locking: iPhone Lock Button Pressed -> Audio Paused
Unlocking: iPhoneUnlocked Button Pressed -> Audio Resumed -> Slide to Unlock -> App Appears
I want the Unlocking sequence to be:
Unlocking: iPhoneUnlock Button Pressed -> Slide to Unlock -> Audio Resumed -> App Appears
I am using OS 2.2.1 and AVFoundation Framework, and here's what I have already tried:
I tried to use applicationWillResignActive and applicationDidBecomeActive callbacks of the AppDelegate, it doesn't work. Although applicationDidBecomeActive is called at the correct time (i.e. when user has slided to unlock the device), the audio gets resumed as soon as unlock button is pressed (I guess it is because of the audio sessions), so I tried:
I implemented audioPlayerBeginInterruption and audioPlayerEndInterruption selectors of the AVAudioPlayerDelegate, it looks like these methods never get called (I have placed log calls). I'm sure I am setting the delegate properly since audioPlayerDidFinishPlaying is correctly called when an audio file has finished playing.
P.S: I am testing on device if that wasn't obvious
They apparently only get called when an Audio session was interrupted, that's to say if you were playing audio and it is being interrupted by other audio which requests an active session.
In short: they dont get called when the phone becomes inactive, but they get called when you receive a call for example.
But even then they only get called when the AVAudioplayer was active at the time.
I'm still wrestling with that crappy system...
Slight abuse of the system, but you can observe the file protection notifications to find out when the device was unlocked. You could use that to decide when to play the audio again.

Resources