applicationWillTerminate and background: terribly confused - iphone

I understand that applicationWillTerminate is no longer called in iOS4, practically. But I have this situation:
my audiobook goes in background mode and keeps playing audio;
until version 3.x of SDK I saved the point where one listened to the MP3 file, in applicationWillTerminate;
now I was told to keep this saving in applicationWillTerminate (for iPhone 3G) and to implement the same method in applicationDidEnterBackground: but this saves NOT the point where user was at the end, just the point when he entered the background...
But, which is the moment, or better the invoked method, where user exits the application from the application dock? Does this exist?
ApplicationWillTerminate is called when there is a memory problem, but really I can't figure what happens when the user himself shuts down the app.
I repeat: applicationDidEnterBackground does not help me because when the user enters in background mode, he can stays in this position for a long time listening to the audiobook and when he starts again the app, after this is shut down, I mean, he will find the position of the audio file when he entered the background mode…
I'm really confused…
Thanks for your help!

You should save the play location automatically in applicationWillResignActive:, applicationDidEnterBackground: regardless of whether the audio keeps playing or not. Then put another save in applicationWillTerminate. That way the last play location is saved regardless of what happens next. The next event simply overwrites the saved play location to update it.
An even better option would be to have the audio player object itself trigger the save whenever it is interrupted e.g [AVAudioPlayerDelegate audioPlayerBeginInterruption:] or similar. It might takes some extra work but it would guarantee that the play location was always saved regardless of the cause of the interruption.

Related

App launched from the first screen from the foreground ios

When I pressing "home" button, app calling - (void)applicationWillResignActive:(UIApplication *)application, ok its good, but when I wait for a some time (10-15 mins), app starting from first loading screen, why? I have added:
[UIApplication sharedApplication].idleTimerDisabled = YES;
But not success. I think it goes to suspended mode, how do I prevent this? Thanks.
It means that your app has been killed by the system.
You can't prevent it completely, the system kills background apps when it needs more memory, but you can do something like this:
free as memory as you can when the app goes in background: doing this, when the system needs memory, your app won't be one of the first to be killed because its footprint is low.
Since you can't be sure that your app won't be killed, use state preservation / restoration: Link
EDIT:
since your app needs to reproduce audio in the background (as written in the comments) I give you some extra advices.
remember to register your app background mode (from this link: Multitasking guide) --> "by including the UIBackgroundModes key (with the value audio) in its Info.plist file"
the app continues to work in the background since it's playing audio, but when the audio is suspended the app is suspended too (it means that it can be killed). So, you must use state preservation to restore it when the user comes back.
Another extract:
"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."
You app has exited. If you want it to come back to where you left off you'll have to preserve the state somehow, check on launch, and then restore the state.

Iphone sdk - How to play a sound during a phone call after some elapsed time?

Well I am having two issues that i can't get to work, related to audio and calls.
The first one is to play a sound during a phone call. I don't want to play continuous music or stream anything, it is just a simple and short sound that the user will hear at one time during his call.
I have read some posts claiming that this is possible, and I even have an application that does so, but I can't get it to work. My app identifies the call using CTCallCenter and print the logs but never plays the sound or plays it after the app comes to foreground again. I have the .plist property of required background mode App plays audio.
The second issue, is to play the sound after some elapsed time. NSTimers doesn't work when on background mode, nor NSThread sleep on my background process or NSOperation. So how could I play this sound after say 10 seconds of the call?
Also, this behavior has to work also when the application is already on background mode. With CTCallCenter I am only getting the event when the application is interrupted from use, but I don't see any logs when i send the app to background and then begin/receive a call
.
If anyone could point me to the right direction I'll be really grateful.
I havent done this, but NSLocalNotifcation, schedule a notification to play when you app get the call to move into the background. I would expect this to work. Interested to find out if it does.

App not playing sound when screen turned off, but doing everything else as it should?

I have an alarm clock app which works on a timer. When the alarm is meant to go off and the screen is switched off, it should start playing audio from AVAudioPlayer, but it doesn't. Then when i turn the screen back on, i can see that the rest of the code fired as expected (a stop button is now on the screen). How do i get the AVAudioPlayer to play when the screen is turned off?
Is there any way for me to detect that the screen is turned off?
#zoul is correct that using the default audio session category will result in sound form your app being disabled when the user locks the screen. See the Audio Session Programming Guide for direction on which audio session category you should choose.
However, even once your audio session category is set correctly, you'll have another issue to tackle. When the screen is switched off, your application gets suspended per Apple's documentation here: Executing Code in the Background. This means that when the user locks their phone or switches to a different app, your app will stop running and stay in a freeze-dried (task-suspended) state until the user activates your app again. At that point, your app resumes execution as if nothing happened. That's why it appears that your app has continued to function when you unlock the screen.
For alarm behavior, you'll probably want to schedule the delivery of a local notification. A local notification will ensure that the system provides your alert to the user at the time you request, and allows the user to activate your app. See Scheduling the Delivery of Local Notifications for details on how to accomplish this.
Maybe you have the wrong audio category? See the documentation for AVAudioSession, especially the audio category settings.

Multitasking: Stop Background Audio at Specific Time

I am developing an iphone app which uses background audio (on an infinite loop) to continue playing after the app has entered the background.
My problem is I want to implement a "sleep timer" which stops playback after a specified period of time.
Is this possible? I have spent an hour looking for a method to do this with no avail.
EDIT: My current thought is to use a lower level API, the Audio Queue Services, and manually re-fill the queue with another instance of the loop during the AudioQueueOutputCallback. If the timer has expired I do not fill the loop. I'm assuming this should work since the documentation says audio callbacks are still fired when an app is playing multitasking background audio. Can anyone think of a better way or a reason why this wouldn't work?
While you queue sound data on the background your app remains fully functional and running as if it was in the foreground (well almost), so yes, you should just write a timer that stops the playback at a given time and it will be fired as expected.
Now to the second question: once you stop queueing things up, your app will be "frozen" until the user manually brings it to the foreground... So what you should do is start queueing audio data from the second file before the first one is done playing, and if you DO need to pause or stop, maybe a solution is to play 0 bytes (silence)?
I'm not actually sure this would be allowed in the App Store. An app is not allowed to execute at all in the background, with the exception of VoIP apps and push notifications.

UIAccelerometer is Shaking

I want a functionality in which i want to detect if my device is being shaked.The problem is i can detect the shake with didAccelerate method of UIAcceleratorDelegate , but i dont know how to detect if the device is still shaking. I want to play an audio file when the user shakes the device for first time,i have to check if the user is still shaking the device while playing the 1st audio file,if it is still being shaked, then i have to play another file.
See the sample project GLPaint from Apple which was found by visiting http://developer.apple.com/iphone and entering "shake" in the search box. Developer account not required.
You might consider writing a Method that runs in a separate thread that polls wether your device is being shaken every now and then and fire events that you handle somewhere else in your code (or instead of that, handle whatever you want to handle within the threads context itself, even tough i would not recommend doing that).
You just have to make sure, that your "shake-detektor"-thread exits at some point in time, you probably want to do that when the second audio file stopped playing. So your loop could test on that condition.
Hope I could help a bit.