I have an application where there are 3 tabs to calculate distance and all. When I first launch the app, on clicking 3 rd tab some network call is happening. Now I put the application to background.
When the application comes to foreground, it should call viewwillappear to go for the network call again. but it is not happening. it is not calling viewwillappear.
How can I check when application comes to foreground, it should check for 3rd tab and call network method
Please help me
When application comes to foreground,
- (void)applicationWillEnterForeground:(UIApplication *)application;
of the app delegate is called.
You can restart all your paused tasks in:
- (void)applicationDidBecomeActive:(UIApplication *)application;
- (void)applicationDidEnterBackground:(UIApplication *)application
{
//save in NSUserDefaults (or wherever) which tab is currently active
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// read from NSUserDefaults which tab was active before,
// and use an IF statement to control the further behavior
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
if(tab3){
[viewController3 netWorkCallFromHere];
}
}
in this approach you will have to declare BOOL tab3 in Appdelegate.
set it true in third viewController and set it false in another viewController .
when it returns from the background then it will check the flag and it will work accordingly.
- (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
{
NSLog(#"%d",tabBar.selectedIndex);
if (tabBar.selectedIndex == 2) {
NSLog(#"Your work");
}
}
Related
I have built a simple apps that connect to a sqlite database, and the app uses storyboards for UI. On first time, it will throw up a login view. If my authenticate was successful, I change my status in the sqlite database to 1. By default, it is 0. After login, I can use the app.
For example if I kill the app, how can I know my app has been killed? I need to change the status become default again. so whenever I click on the app again, I have to sign in again.
Any idea how to do this? thanks.
Your application delegate implements several methods which handle state changes in your application. From the UIApplication.h header.
- (void)applicationDidFinishLaunching:(UIApplication *)application;
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions NS_AVAILABLE_IOS(6_0);
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions NS_AVAILABLE_IOS(3_0);
- (void)applicationDidBecomeActive:(UIApplication *)application;
- (void)applicationWillResignActive:(UIApplication *)application;
- (void)applicationWillTerminate:(UIApplication *)application;
You can implement whichever methods are relevant, in this case the applicationWillTerminate method to change state. Alternatively, always throw up a login view in applicationDidBecomeActive. (This doesn't, however solve the issue updating the database. If the database is local, there's no problem, simply change the database before resigning or terminating. The challenge here would be if your database lives on a server. Although it might bot be an issue, I could see connection timeouts affecting the integrity of the remote values.)
These methods are added to your project automatically in your application delegate, which can be found in the AppDelegate.h & AppDelegate.m files.
For a complete explanation, have a look at the UIApplication Delegate protocol reference.
You can perform close down actions in,
- (void)applicationWillTerminate:(UIApplication *)application
{
// Log out?
}
You can also do the same if your app isn't killed but just gets suspended, such as during an incoming call,
- (void)applicationWillResignActive:(UIApplication *)application
{
// Log out?
}
or,
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Log out?
}
Alternatively, on resume,
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Log in?
}
or,
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Log in?
}
You can't detect if you app was killed, since the process of you app gets killed by the system and no code is called to inform your app that it has been killed.
What you want is to set te some kins of boolean in :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
Since this is called if you restart the app after it has been killed.
For the other states seen the answer by Moshe
EDIT
use the delegate methods
such as:
applicationWillResignActive
I already use the:
(void)applicationDidEnterBackground:(UIApplication *)application {}
method, but I can't differentiate if is because press the home button or the on/off button.
Thanks in advance,
For the on/off button(or an incoming call or SMS):
- (void)applicationWillResignActive:(UIApplication *)application
For the Home button:
- (void)applicationDidEnterBackground:(UIApplication *)application
With the notification of applicationWillResignActive, applicationDidBecomeActive will still enter while you are entering in background. But there is a way to differentiate by getting the state of the app, so try this in applicationDidEnterBackground.
- (void)appHasGoneInBackground {
bool inBackground = [UIApplication sharedApplication].applicationState == UIApplicationStateBackground;
// lockScreen state
if (!inBackground) {
// do something
}
}
Apple's UIApplication-class reference
Use - (void)applicationDidEnterBackground:(UIApplication *)application {} when your app is entering the background (home button) and - (void)applicationWillTerminate:(UIApplication *)application when it's about to be closed (on/off button or iOS call to close after a random time in background).
My understanding is that when you lock or unlock your iOS device your application delegate will call - (void)applicationWillResignActive:(UIApplication *)application and - (void)applicationDidBecomeActive:(UIApplication *)application, respectively. Locking and unlocking are similar to receiving an interruption like a phone call. Sending your application to the background by hitting the home button calls different methods, namely - (void)applicationDidEnterBackground:(UIApplication *)application and - (void)applicationWillEnterForeground:(UIApplication *)application.
I am using following functions in my App delegate
- (void)applicationWillResignActive:(UIApplication *)application {
NSLog(#"applicationWillResignActive");
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSLog(#"applicationDidEnterBackground");
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
NSLog(#"applicationWillEnterForeground");
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
NSLog(#"applicationDidBecomeActive");
}
- (void)applicationWillTerminate:(UIApplication *)application {
NSLog(#"applicationWillTerminate");
}
All functions are working fine. But When i Delete the app from the Background by clicking "-" red button in the background tasks, and again open the app. no function has been called. What should i use instead of all the above functions..have any ideas?
What exactly i need is ..i need to save the application state when it has been deleted from the background using "-" red button and restore it when ever it opened.
You should save the state of the application when it enters background mode (-applicationDidEnterBackground). No delegate methods are called when a background app is terminated.
You should find a lot of useful informations about this in the iOS Application Programming Guide.
I am sending Push Notifications to my iPhone app, and I'd like a different set of instructions to execute depending on whether the app is already launched or not. I'm new to iPhone development, and while I suspect UIApplication or my project's AppDelegate class has the solution, I haven't found a good answer. Is there an easy way to check for this?
Here's the more appropriate way of handling active/inactive state of the app.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
// check for the app state
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateActive) {
//the app is in the foreground, so here you do your stuff since the OS does not do it for you
//navigate the "aps" dictionary looking for "loc-args" and "loc-key", for example, or your personal payload)
}
application.applicationIconBadgeNumber = 0;
}
didReceiveRemoteNotification: is called when the app is running, yes, but when it is suspended, the iOS takes care of putting up the badge, etc. If the app is in the foreground, the OS does nothing, and just calls your didReceiveRemoteNotification:.
Depending upon what you mean by "launched", you are either looking for:
Kevin's answer above (differentiates between launched or not launched)
or this (differentiates between suspended or active, but already launched):
Use a flag that is set true when the application becomes active, and false when the application is not active.
Flag (in header file [.h]):
BOOL applicationIsActive;
Code (in implementation file [.m]):
- (void)applicationDidBecomeActive:(UIApplication *)application {
applicationIsActive = YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
applicationIsActive = NO;
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if (applicationIsActive) {
// Handle notification in app active state here
}
else {
// Handle notification in app suspended state here
}
This works because when the application is suspended, the OS calls "applicationDidReceiveRemoteNotification" before it calls "applicationDidBecomeActive" during the "wake-up" process.
The "complete" answer is actually Kevin's answer plus this answer.
Hope this helps.
The UIApplication delegate has the method
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
which you need to implement. This receives the notification when the app is running.
If your app is not currently running and a notification is received then your app can be launched with
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
with the notification details held in the launchOptions dictionary. if the dictionary is nil then the user tapped the application icon as normal.
If you are going to check applicationState on iOS less than 4, you'll need to check that applicationState is supported:
if ([application respondsToSelector:#selector(applicationState)] ){
// Safe to check applicationState
UIApplicationState state = [application applicationState];
}
The Apple documentation for push notifications explains this:
However, there are two situations where applicationDidFinishLaunching: is not a suitable implementation site:
The application is running when the notification arrives.
The notification payload contains custom data that the application can use.
In the first case, where the application is running when iPhone OS receives a remote notification, you should implement the application:didReceiveRemoteNotification: method of UIApplicationDelegate if you want to download the data immediately. After downloading, be sure to remove the badge from the application icon. (If your application frequently checks with its provider for new data, implementing this method might not be necessary.)
This means that if your application:didReceiveRemoteNotification: delegate method is called, your app is running.
I'm trying to handle phone calls and standby and things of that nature. I added the function
- (void)applicationWillResignActive:(UIApplication *)application
and
- (void)applicationDidBecomeActive:(UIApplication *)application
to my UIApplicationDelegate. When coming out of standby, "applicationDidBecomeActive" always gets called. However the issue is "applicationWillResignActive" never gets called.
I was wondering if anyone has run into this issue and whether or not anyone found a reason.
EDIT
More info, I discovered that my engine's update loop that gets run from applicationDidFinishLaunching was causing me to miss the message. I call
while(CFRunLoopRunInMode(kCFRunLoopDefaultMode, .002, FALSE) == kCFRunLoopRunHandledSource);
to catch all iphone messages but it doesn't seem to catch the resignActive message before becoming inactive.
Attempting to fork a thread for my update loop is causing weird crash bugs. Anyone have any quick fix suggestions?
Its getting called in iOS 4.0 , when the Home button is hit.
The following delegate methods are called when the Home button is hit in iOS 4.0
- (void)applicationWillResignActive:(UIApplication *)application
{
NSLog(#"Application Did Resign Active");
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
NSLog(#"Application Did Enter Background");
}
And when you double tap the home button and again relaunch the App , the following delegate methods are called .
- (void)applicationWillEnterForeground:(UIApplication *)application
{
NSLog(#"Application Will Enter Foreground");
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
NSLog(#"Application Did Become Active");
}
I don't think
- (void)applicationWillResignActive:(UIApplication *)application
is called when a phone call is received. I think the OS waits for the user to either answer or declines the phone call. If it i declined, then the app says alive and
- (void)applicationDidBecomeActive:(UIApplication *)application
is called. If it is answered, then your app is told to exit and it will receive
- (void)applicationWillTerminate:(UIApplication *)application
Be sure to allow
- (void)applicationDidFinishLaunching:(UIApplication *)application
to return before running your game loop. One technique is to use the function
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay
on the application delegate and run your game loop after a delay of say ".01" After you do this, the message should be able to fire properly. I believe the reason for the message stomping was because the run loop was stuck on applicationDidFinishLaunching and wasn't able to push any other UIApplicationDelegate messages onto the queue.
- (void)applicationWillResignActive:(UIApplication *)application {
/*
Sent when the application is about to move from active state 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.
*/
}