Is there a way i could stop an app from going into background ? Or is there a way in which i could bring my app to foreground if it did go into background ?
I'm making a showcase app for a client and the app must always run on the iPad without interaction from the user.
You can force your app to stay active using following code
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
But if you press home button of device, the app will go in background. You cannot force to stop this.
In this case you can use UILocalNotification to bring the app to the foreground if the device is locked, a notification appears, and the user unlocks the device or if user tap on the notification.
You can also fire a local notification whenever user going to background in
applicationDidEnterBackground: method
UPDATE - a warning to anyone with similar symptoms... check Do Not Disturb is not active!
I finally paid to get an app I was working on running on my iPhone instead of on the simulator.
Having done so I've spotted a strange behaviour with regards to the UILocalNotifications that I create, which are set to use the default sound UILocalNotificationDefaultSoundName, and the default timezone ([NSTimeZone defaultTimeZone]).
If the app is foregrounded then the local notification fires on time and I receive it within
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
and I create an alert view to display it.
If however I lock my phone just before a notification is expected then nothing appears on the screen, but when I press the home button to show the lock screen I can see my app's notification in the notification centre on the lock screen. No sound was played, but then again the phone didn't wake up to show the notification properly.
If however I just press the home button so the app is put in the background leaving me looking at the springboard apps then I don't see any notifications whatsoever, and again no sound is heard.
On the simulator the same code correctly fires the notification banner when looking at the app icons in the spring board, although I've never been able to hear any sounds for the notification. But as the simulator doesn't let you configure the notification centre for apps I always presumed it was perhaps set to not allow sounds. On my device sounds for this apps notifications are enabled, and i've tried it with banner and alert modes, with no joy. Very frustrating.
Has anyone experienced this, or have an idea what could be going on?
Oh the irony of this answer.. think it's time to go to bed. My iPhone thinks that too for nearly 3 hours now... My question happily describes Do Not Disturbs behaviour, which was active.. Sorry to waste everyones time!!
My app checks the GPS while my app is not the active app and I use AVAudioplayer too in background.
It works fine and stays in the background doing its thing, but ios7 displays this red top banner with my app name flashing on it when it is not the active app.
How can I disable this banner, it is annoying to use other apps that are squished down 1 line?
I know this can be done as I have other GPS based background apps that don't display this flashing banner.
EDIT - So we found the answer quickly but the solution evades me:
If I stop OpenEars pocketsphinxController from listening with a button that calls this method while the program is active, the banner disappears when the app loses focus:
-(void) mystopListening{
NSLog(#"Tried to stop listening");
[pocketsphinxController stopListening];
}
BUT if I call the same method from my app delegate with (I had to import my view controller.h file in my app delegate.h and add -(void) nystopListening; in my view controller.h to make the below execute properly):
- (void)applicationWillResignActive:(UIApplication *)application{
myViewController * vc = [[myViewController alloc]init];
[vc mystopListening];
}
The banner persists! It is a little like ios7 has decided I am a recording culprit before I even have a chance to turn it off. OR, am I even turning it off?
How do I do this effectively and in what event?
EDIT - So it turns out I am not really turning pocketsphinxController off when 'mystopListening' is called from the app delegate. I know this because it DOES log the 'Tried to stop listening' when called from app delegate but the pocketsphinxController does not respond with its 'pocketsphinxDidStopListening' method. PocketsphinxController does call its 'pocketsphinxDidStopListening' method when I call 'mystopListening' from a button while the app is active.
Why won't the pocketsphinxController respond when called from from the app delegate, I must be doing it wrong?
Thanks,Carmen
Turns out I was not really calling the original pockectsphinxcontroller instance from my app delegate.
As a workaround to the problem I did this:
My app always has a timer running, so in my app delegate where I get notice of when app goes to inactive and comes back active, I just set global flags so my timer can know app active status. Then my timer just uses pockecsphinxcontroller methods to stop and start listening and voila, the banner is no more while app not active.
Is there an API that allows me to know when NotificationCenter will pop a notification on the top of the screen while my app is running (for example for an incoming Message or email)?
It causes a big performance glitch to my game so I'd like to pause it and unpause once the notification has disappeared. If there is no event to listen to I can only think of monitoring FPS and pausing for a few seconds if it drops below a threshold. Any other suggestions?
EDIT: My answer is only for popup notifications, not for the ones that scroll on to the top of the screen. Sorry :(
In your app delegate, the method
- (void)applicationWillResignActive:(UIApplication *)application
will be called.
And then
- (void)applicationDidBecomeActive:(UIApplication *)application
when it's time to start up again.
Which is the proper delegate to implement when an application is waking up from being in the background and you want it to prep it to be active?
applicationWillEnterForeground vs applicationDidBecomeActive -- What's the difference?
Which is the proper delegate to implement for when an application is going to sleep and you want to prep it to cleanup and save data?
applicationWillResignActive vs. applicationDidEnterBackground -- What's the difference?
Also, I've noticed that applicationWillResignActive gets called when an incoming SMS or call comes in but the user chooses to click Ok and continue. I don't want my app to take any action in these cases. I just want it to keep running without any intermediate cleanup since the user didn't exit the app. So, I would think it makes more sense to do cleanup work just in applicationDidEnterBackground.
I would appreciate your input on best practices to follow on choosing which delegates to implement for waking up and going to sleep as well as considering events like being interrupted by SMS/calls.
Thanks
When waking up i.e. relaunching an app (either through springboard, app switching or URL) applicationWillEnterForeground: is called. It is only executed once when the app becomes ready for use, after being put into the background, while applicationDidBecomeActive: may be called multiple times after launch. This makes applicationWillEnterForeground: ideal for setup that needs to occur just once after relaunch.
applicationWillEnterForeground: is called:
when app is relaunched
before applicationDidBecomeActive:
applicationDidBecomeActive: is called:
when app is first launched after application:didFinishLaunchingWithOptions:
after applicationWillEnterForeground: if there's no URL to handle.
after application:handleOpenURL: is called.
after applicationWillResignActive: if user ignores interruption like a phone call or SMS.
applicationWillResignActive: is called:
when there is an interruption like a phone call.
if user takes call applicationDidEnterBackground: is called.
if user ignores call applicationDidBecomeActive: is called.
when the home button is pressed or user switches apps.
docs say you should
pause ongoing tasks
disable timers
pause a game
reduce OpenGL frame rates
applicationDidEnterBackground: is called:
after applicationWillResignActive:
docs say you should:
release shared resources
save user data
invalidate timers
save app state so you can restore it if app is terminated.
disable UI updates
you have 5 seconds to do what you need to and return the method
if you don't return within ~5 seconds the app is terminated.
you can ask for more time with beginBackgroundTaskWithExpirationHandler:
The official documentation.
Managing Your App's Life Cycle is helpful to your questions. For quick concept, you can see Figures in that document.
You can also read the comment from the code generated by the XCode Wizard. Listed as follows:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
/*
Sent when the application is about to move from active to inactive state.
This can occur for certain types of temporary interruptions (such as an
incoming phone call or SMS message) or when the user quits the application
and it begins the transition to the background state.
Use this method to pause ongoing tasks, disable timers, and throttle down
OpenGL ES frame rates. Games should use this method to pause the game.
*/
}
- (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.
*/
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
/*
Called as part of the transition from the background to the active state;
here you can undo many of the changes made on entering the background.
*/
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
/*
Restart any tasks that were paused (or not yet started) while the
application was inactive. If the application was previously in the
background, optionally refresh the user interface.
*/
}
- (void)applicationWillTerminate:(UIApplication *)application
{
/*
Called when the application is about to terminate.
Save data if appropriate.
See also applicationDidEnterBackground:.
*/
}
For more detailed explanations, please refer to official document for UIApplicationDelegate
I was still a bit confused with Dano's answer so I did a little test to get the flow of events in certain scenarios for my reference, but it might be useful to you too. This is for apps that DO NOT use UIApplicationExitsOnSuspend in their info.plist. This was conducted on an iOS 8 simulator + confirmed with iOS 7 device. Please excuse Xamarin's event handler names. They are very similar.
Initial and all subsequent launches from a not-running state:
FinishedLaunching
OnActivated
Interruption (phone call, top slide-down, bottom slide-up):
Home button double-press listing inactive apps, then reselecting our app:
OnResignActivation
OnActivated
Home button double-press listing inactive apps, selecting another app, then relaunching our app:
Home button single press, then relaunch:
Lock (on/off button), then unlock:
OnResignActivation
DidEnterBackground
WillEnterForeground
OnActivated
Home button double-press, and terminate our app: (subsequent relaunch is first case)
OnResignActivation
DidEnterBackground
DidEnterBackground (iOS 7 only?)
Yes, DidEnterBackground is called twice on iOS7 device. Both times UIApplication state is Background. However, iOS 8 simulator does not. This needs testing on iOS 8 device. I will update my answer when I get my hand on it, or someone else could confirm.
applicationWillEnterForeground is called:
when app is relaunched(comes from background to foreground)
This method is not invoked when app starts for the first time i.e when applicationDidFinishLaunch is called but only when comes from background
applicationDidBecomeActive
applicationDidBecomeActive is called
when app is first launched after didFinishLaunching
after applicationWillEnterForeground if there’s no URL to handle.
after application:handleOpenURL: is called.
after applicationWillResignActive if user ignores interruption like a phone call or SMS.
after disappearing of alertView anywhere from the application
applicationWillResignActive is called when system is asking for permissions. (in iOS 10). Just in case someone hit into the same trouble as me...
In iOS 8+ there is a subtle but important difference for taking phone call.
In iOS 7 if user takes phone call both applicationWillResignActive: and applicationDidEnterBackground: are called. But in iOS 8+ only applicationWillResignActive: is called.
For iOS 13+ the following methods will be executed:
- (void)sceneWillEnterForeground:(UIScene *)scene
- (void)sceneDidBecomeActive:(UIScene *)scene