using applicationWillTerminate to delay shutdown as long as possible - iphone

I've noticed that several iPhone apps, especially some more graphically intensive games take quite a while to exit when the home button is pressed.
My question is, weather it's possible to artificially recreate this situation, the reason being, that I'm trying to implement a sort of "phone protector" that starts making loud noises when some accelerometer data is read. The idea would be to have the AVAudioPlayer keep playing the sound for as long as possible (ie. until the iPhoneOS decides to kill the process for good).
I tried something like this in my app delegate, just to see how it reacts:
-(void)applicationWillTerminate:(UIApplication *)application{
NSInteger i;
while(true) {
i++;
}
}
What happens though, is that the home screen comes up immediately and the sound stops playing (the AVAudioPlayer instance is in a view controller), but the applications process is still in memory and in fact stops me from launching a new instance of the app until the old one is killed manually (this is all in the Simulator).
Any ideas?

You really need to test this on a real device.
I have the feeling that you get 6 seconds to exit, after which you will be killed.
By the way, AVAudioPlayer, might be being a good citizen and getting out of the way.
It does some strange and even annoying things under the hood. In this case you'll need something lower level, like a remote io audio unit. I know for a fact that if you don't stop this in applicationWillTerminate then it will happily go on making sound for a moment in the home screen.

As it turns out, AVAudioPlayer doesn't actually behave like a good citizen, however I was using it's callback when finished playing to loop the sound, but for some reason that didn't work after applicationWillTerminate got called. Using numberOfLoops = -1 and adding an loop (i++; didn't work, NSLog(#"qwerty") did) to the app delegate did.
Funny enough, the sound actually continues to play forever. I'm using the official SDK, but with a jailbroken phone.

Unfortunately I couldn't associate the cookie based user I have at my work computer with my OpenID, so I couldn't reply properly.
Anyway, I'm using 3.0 and the same exact thing happens on both the simulator and the device. I can't test on a non-jail broken phone at the moment, because Apple is taking forever and then some to approve our license, even though we already have several apps coded and ready for launch...
I'll let you know as soon as I find out.

Related

Execute code upon app termination in swift

I'm new to swift and programming so I'm not sure if or how this is possible, but could anyone tell me if I can designate code to be executed when the user terminates the app from the multitasking menu? I just have a line of code that I would like to execute at that time, but I'm not sure where to put it in my project.
Thanks!
If the user terminates the app from the multitasking menu, your app is killed dead. It is not terminated "in good order". You do not get an event at that time. It's just like the scene in 2001: A Space Odyssey where the scientists are already in suspended animation and HAL pulls the plug on them.
The art of Cocoa / iOS 8 programming is the art of the possible. Adjust your desires to fit the reality of the events you do get. You get an event when the user leaves your app, so if there is something you need to be sure to do, do it then, as you may never get another chance.
As matt said, when the app is terminated from the multitasking menu, none of your code is run, it's just killed.
Try putting your code into the application delegate's applicationWillResignActive(_:) method. This will run any time your app becomes inactive, though. In other words, more often (all the time) than being terminated in the multitasking menu. It'll run when there's an incoming phone call or text, I believe it will run if there is a notification with an alert, it will run when the user presses the home button.

how to keep getting "accelerometer:didAccelerate:" when app in background

How can my app keep getting a call to its "accelerometer:didAccelerate:" method of UIAccelerometerDelegate IF another app interrupts my app, such as the iPhone user receiving a phone call?
My app measures motion, but stops if suspended by the user, or if interrupted by another app.
I know this has been difficult in the past, but maybe there is something new in iOS.
Thanks!
You can't, apple standards are to block the app when a proccess pops in, It freezes the app at the moment it was interrupted. If finishes the last proccess it started in the background then it freezes the app. If you find a way around it i'd love to know it. Here is something that might help you to find the solution stackoverflow post similar to your question

Play sound at specific time while app is in background

I'm looking for some way to let my app play a sound at a specific time while it's in the background (IOS4 multitasking). Currently, I use local notifications for that which works quite well, except for:
the sound will not be played if the phone is muted
the 30 second playback limit
I saw there's setKeepAliveTimeout:handler: but it's only available for voip-apps and since that's not the purpose of my app, I guess Apple would reject it because of this. I also saw a solution where an "empty" sound is being played until it's time has been reached, but - ignoring that this is not a very elegant way, anyways - I read that this, too, might get the app rejected.
Since there are a few alarm clock apps that do just what I'm looking for, I wonder how they implemented this functionality.
Thanks for any hints in advance!
If you seek a solution that will be approved by Apple, you're right you can't use the setKeepAliveTimeout:handler and even if you could - you can't set the timeout to something that's smaller than 600 seconds, so I guess it won't be of a great use anyway (besides that It's not guaranteed to fire the event even remotely close to the timeout you specified. For example, I set it to 600 seconds and some event fired as early as 360 seconds..).
About playing the silent sound, except the waste of battery, if you're app has legitimate use for background audio (if you're implementing an alarm clock, that's pretty obvious), I don't see a reason for your app to be rejected, as long as you don't try to use other background features (GPS signal, VoIP handlers, etc).
Here's one example app that used this "feature" for their benefit:
http://tapbots.com/blog/pastebot/pastebot-music-in-background
About other methods, you can look in this thread:
How do I start playing audio when in silent mode & locked in iOS 6?
On a personal note, it's not very easy to cope with background policies of Apple. Me and my company had (have?) a hard time just to maintain a simple VoIP connection due to all the limitations. My best advice is try to do as less as possible in the background as you can. If the UILocalNotificaion solution suits you, you'll probably should stick to it and live with the limitations.

iPhone, is it possible to play a sound from the speakers while in a call?

I would like to know from some iphone-Audio expert if there is a way to let a sound play through the line in of the microphone, or at least to play from the speaker (not the receiver) during a call.
I've tried different combinations of AVAudioSessionCategory with kAudioSessionProperty_OverrideAudioRoute, but I've noticed that when the iphone is in a call, it plays sounds only through the receiver.
My best try for the moment is to pick the call in speaker mode, and put the AVSession sound in AVAudioSessionCategoryAmbient, but the result is too bad.
I repeat: i would like to play a sounds through the speaker while listening the call through the receiver.
I've used this in: http://www.pallaudio.com , the app that lets you lie at the phone!
I'm curious as to what you're trying to achieve by doing so? Besides the fact that this could get your app rejected for non-standard behaviour (I'm sure Apple has some guidelines related to apps playing sounds during a call), this also seems like a sure-fire way to tick off a user (although maybe that's what you're trying to do).
Very simply. It does it by playing the sound during a call initiated by ANOTHER device.
Fooled me too for a minute there...same deal as another app, called "Escape Pod".
Check out http://theamazingaudioengine.com/
It does have the capability to do this. From a user point of view though, I know sometimes Apple will throw a complaint about running sounds through the main speaker while the receiver is enabled at the same time too. Hopefully though, as long as you're not just planning on running fart sounds through the speaker, you should be ok.
ok, after long finding, the answer is simply: NO!

NSTimer callbacks while iPhone application is inactive

This question seems to be the essence of several others on this forum. I believe that it is possible for the active iPhone application to continue running, and specifically, to continue receiving timer call-backs, after it has entered the inactive state (either through the idle timer kicking in the screen lock, or through the user pressing the hardware lock button).
The documentation specifically says that while an application is inactive, it is executing, but not dispatching incoming events (I'm not giving a link because I'm jumpy about NDA - should I relax about that? Is this whole post a breach? sigh).
Also, two answers by user "Ambr Str" directly state that it is possible to continue receiving timer call-backs, and he supplies a snip of code to achieve it (I can't link to this because I'm a new user, sorry - search for the question: "What happens to an iPhone app when iPhone goes into stand-by mode?" to find his answer).
I've tried to create my call-backs as he suggests, but once my application becomes inactive, the call-backs cease firing.
I've just noticed that while the iPhone is plugged in, if the application becomes inactive (due to idle time out or me pressing the sleep button), call-backs do continue to occur - perhaps I should get my users to carry a battery pack with them ;-)
There is a good answer to this question on Apple's forums. Search for "Timer" and "Eskimo" (the helpful chap who provides the answers).
In brief, shortly after the application becomes inactive, the phone really does go to sleep. The only way to prevent this is to be playing some audio (or for some audio to be playing in a background application). While audio is playing the phone will not sleep, and your application continues to be run.
It is suggested that playing stay awake audio is a hack, and that you shouldn't do it if at all possible. I think in my application (which performs audio playback interspersed with silent periods), the approach is valid, if not ideal!
I have an app. which includes an embedded webserver. I'm planning to offer an option of disabling auto-sleep IFF the server is turned on, AND the device is on power. So you might consider checking the batteryState property of UIDevice. So if batteryState != UIDeviceBatteryStateUnplugged, go ahead and disable idle timer. (note: the docs say that UIDeviceBatteryStateUnknown will be returned when in simulator.)
You'll also want to listen for UIDeviceBatteryStateUnplugged notifications and set batteryMonitoringEnabled appropriately.