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
Related
In my app I am increasing the brightness of the screen at some part and of course I need to return it back to its value before exiting my app. But I can't catch if the user uses the button and puts the app to the background. Is there any way to understand if the app will work on background so at that point I can change screen brightness to its old value.
You need to implement your code by using the following AppDelegate methods, and this is the way to go
- (void)applicationDidEnterBackground:(UIApplication *)application
- (void)applicationWillEnterForeground:(UIApplication *)application
- (void)applicationWillResignActive:(UIApplication *)application
- (void)applicationDidBecomeActive:(UIApplication *)application
For sake of completion I will add that you can do it in your application delegate like others have already said so.
But some time it don't make sense to do this in the application delegate, and for those case there is NSNotification for that like : UIApplicationWillEnterForegroundNotification. You will find those notification at the bottom of the UIApplication class reference.
Implement code in
- (void)applicationWillResignActive:(UIApplication *)application
and - (void)applicationDidBecomeActive:(UIApplication *)application
in your appDelegate class
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");
}
}
I'm making an app that keeps track of some reminders that repeats with an user defined interval.
I've made it so when the alert displays, the action title says "Renew". When you click this, the app opens, and here I want to create the next reminder, but the problem is that I don't know if the app opens because the notification button was tapped or if the notification fired while the app was running.
Anyone got any ideas?
The 'correct' way to do this is to examine your NSApplication's applicationState property in the application:didReceiveRemoteNotification: method of your delegate.
From the documentation for handling local notifications:
iOS Note: In iOS, you can determine whether an application is launched
as a result of the user tapping the action button or whether the
notification was delivered to the already-running application by
examining the application state. In the delegate’s implementation of
the application:didReceiveRemoteNotification: or
application:didReceiveLocalNotification: method, get the value of the
applicationState property and evaluate it. If the value is
UIApplicationStateInactive, the user tapped the action button; if the
value is UIApplicationStateActive, the application was frontmost when
it received the notification.
This is similar to your solution using flags set in applicationWillEnterForeground and applicationDidBecomeActive but with system support.
I don't know if my question was unclear but it seems that I got 4 different answers that all misinterpreted my question :P
However, I discovered that the didReceiveLocalNotivication happens between willEnterForeground and didBecomeActive, so I did this to determine if the app was already open or not:
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
NSLog(#"Opened from notification? %#", wasInactive ? #"yes!" : #"no!");
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
wasInactive = YES;
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
wasInactive = NO;
}
Look up the documentation for UIApplication launch option keys. The last parameter to your application:didFinishLaunchingWithOptions: delegate method contains the information you need.
Also, look at application:didReceiveLocalNotification.
You're looking for
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
or
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
Documentation
If your application is already running you'll get this delegate message on the app delegate
application:didReceiveLocalNotification:
If it wasn't running you'll have to use
application:didFinishLaunchingWithOptions:
You need to respond appropriately in both methods to cover all cases
UPDATED
To detect if the user activated the action button requires a little more complexity. We can tell that application:didFinishLaunchingWithOptions: will have the local notification as a launch option, but it's more difficult with the application:didReceiveLocalNotification:.
Since the application becomes active after the user taps the button, we have to defer until we see that message (or not). Set an NSTimer in application:didReceiveLocalNotification and cancel it in didBecomeActive. That means the user pressed the action button. If the timer isn't cancelled the user was inside the app when it fired.
In your app delegate in this method:
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
You have to examine the launchOptions looking at this key:
UIApplicationLaunchOptionsLocalNotificationKey
When you are already active this will be called:
- (void) application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
I'm trying to implement OAuth securely as detailed here: http://fireeagle.yahoo.net/developer/documentation/oauth_best_practice#custom-url-osx. I seem to have hit a stumbling block, as I am unable to figure out how to handle a url which launches my application when in the background.
I have registered my application to handle oauthtest. I have confirmed that oauthtest:// and oauthtest://callbacktest both launch my application and operate as intended when my application is not running in the background.
I am implementing
application:(UIApplication *) didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
which is successfully called when my application starts up cold. I can easily get the url passed to my application.
However, if my application is already running in the background, neither
application:(UIApplication *) didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
nor
application:(UIApplication *) handleOpenURL:(NSURL *)url
is called and I have no way of getting the parameters passed to my application as part of the URL.
Does anyone know how to get the parameters passed to a backgrounded application by a custom url scheme?
I am aware that I could work around this issue by disabling multitasking, but I would rather not do that for obvious reasons. Thanks in advance.
Here's some sample code that seemed to work for me, tested in iOS4:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
NSLog(#"handleOpenURL - %#", [url absoluteURL]);
return YES;
}
- (void)applicationDidFinishLaunching:(UIApplication *)application {
NSLog(#"applicationDidFinishLaunching");
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSLog(#"didFinishLaunchingWithOptions - %#", [launchOptions objectForKey:#"UIApplicationLaunchOptionsURLKey"]);
return NO;
}
If I launch the application for the first time, didFinishLaunching: handles the URL. If I then put the app in the background, go back to Safari, and tap a link that brings the app back into the foreground, then handleOpenURL: takes care of the URL. Good luck!
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.
*/
}