Record TimeStamp every time the user uses the app - ios

I would like to record a timestamp whenever the user opens the app. Now, I was able to record in the ViewDidLoad method, however, once the user closes the app and it goes to the background and then open the app once more, I can't get the timestamp, because ViewDidLoad doesn't run anymore. Does any of you have any idea where to put my timestamp code?

You could put it inside - (void)applicationDidBecomeActive:(UIApplication *)application , but it isn't a good approach, since the user starting the app isn't the only activity that will cause the timestamp to be saved, as there are other situations when this method might get called.
From Apple's Documentation
applicationDidBecomeActive: Tells the delegate that the application
has become active.
This method is called to let your application know that it
moved from the inactive to active state. This can occur because your
application was launched by the user or the system. Applications can
also return to the active state if the user chooses to ignore an
interruption (such as an incoming phone call or SMS message) that sent
the application temporarily to the inactive state.
The correct approach is to put the code that stores the timestamp both inside application:didFinishLaunchingWithOptions: and applicationWillEnterForeground:
The first method will get called on the first launch and the second one when the application is launched from the background. Since an ignored interruption wouldn't send the app to the background, applicationWillEnterForeground would not get called in this case, so you wouldn't have a timestamp stored after the user ignores a phone call for example.
Check this answer, since it very well summarizes the role of the methods involved in handling sending an app to the background and getting it back to the foreground and what should you use each of them for.

Implement applicationDidBecomeActive: in your app delegate or observe the UIApplicationDidBecomeActiveNotification notification.

Try using - (void)viewDidAppear:(BOOL)animated:
instead. It is called whenever the view appears on the screen.
Or you can look into the UIApplicationDelegate and try implementing something like:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
or
- (void)applicationDidBecomeActive:(UIApplication *)application

Related

What method of AppDelegate will be called after entering into Suspended state?

My App goes in background, If I open again, It shows same page where I left it.
While, If iOS puts app into Suspended state, yet it is in memory. If I come back, which AppDelegate methods will be called.
Actually my purpose is to restore same screen from suspended to app, if it is not TERMINATED.
Last thing, Will didFinishLaunchWithOptions will be called if App is returning from SUSPENDED state.?
Thanks..
As Apple Documentation states,
application:willFinishLaunchingWithOptions:—This method is your app’s first chance to execute code at launch time.
application:didFinishLaunchingWithOptions:—This method allows you to perform any final initialization before your app is displayed to
the user.
applicationDidBecomeActive:—Lets your app know that it is about to become the foreground app. Use this method for any last minute
preparation.
applicationWillResignActive:—Lets you know that your app is transitioning away from being the foreground app. Use this method to
put your app into a quiescent state.
applicationDidEnterBackground:—Lets you know that your app is now running in the background and may be suspended at any time.
applicationWillEnterForeground:—Lets you know that your app is moving out of the background and back into the foreground, but that
it is not yet active.
applicationWillTerminate:—Lets you know that your app is being terminated. This method is not called if your app is suspended.
so applicationWillEnterForeground and applicationWillResignActive will be get called!
- (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 invalidate graphics rendering callbacks. 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:.
}
didFinishLaunchWithOptions didnt call.
Accoding to application's life cycle, Your app will not get any notification when ios will put your app in suspended mode. Whenever your app enters in background mode and if its not doing anything - not processing - ios will put it in suspended state.
But when suspended and its still in memory, You don't really need to do anything to display same screen where your app was before. ios automatically keep the state of app. You need to manage this only if your app is getting terminate while in suspended mode ..i.e. not in memory.
If you don't have any execution in background with any of background execution method , you can consider app in suspended mode if you receive notification for applicationDidEnterBackground store state of your app somewhere and applicationWillEnterForeground you can display app with stored state.
or if you are executing some finite task in background, You can keep local variable and use that for keeping track of suspended or now. on applicationDidEnterBackground, variable = inBackground, when you task completed and variable == inBackground, set variable == inSuspended and also store state of your app somewhere. on applicationWillEnterForeground
if variable == inSuspended
{
//Display app according to previously stored state.
`variable == inForgorund`,
}
You can test it your self using breakpoints in AppDelegate file.
If user will click on Home button once, app is in suspended state.
If user will click on Home button twice, app is in inactive state.
While user comes from suspended state to the app, I found following method calls.
first : applicationWillEnterForeground then applicationDidBecomeActive.
didFinishLaunchingWithOptions not called.
More details

How to know whether an app is being terminating in iOS?

- (void)applicationDidEnterBackground:(UIApplication *)application {
//...function_a call
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
//...function_b call
}
- (void)applicationWillTerminate:(UIApplication *)application {
//...function_c call
}
I'm tracking my app with AppDelegates methods. Its working fine, if app just go / up from background to foreground. But when I try to remove my app from the running applications then, it will first call - (void)applicationDidEnterBackground:(UIApplication *)application and then, will call - (void)applicationWillTerminate:(UIApplication *)application. How do I know in - (void)applicationDidEnterBackground:(UIApplication *)application that app is being terminating. By mean, I don't want function_a call twice instead it should only call when app goes into background.
Update:
Setting even following observer doesn't help.
UIApplicationDidEnterBackgroundNotification
UIApplicationWillEnterForegroundNotification
UIApplicationWillTerminateNotification
- (void)applicationWillTerminate:(UIApplication *)application:
This method lets your app know that it is about to be terminated and purged from memory entirely. You should use this method to perform any final clean-up tasks for your app, such as freeing shared resources, saving user data, and invalidating timers. Your implementation of this method has approximately five seconds to perform any tasks and return. If the method does not return before time expires, the system may kill the process altogether.
For apps that do not support background execution or are linked against iOS 3.x or earlier, this method is always called when the user quits the app. For apps that support background execution, this method is generally not called when the user quits the app because the app simply moves to the background in that case. However, this method may be called in situations where the app is running in the background (not suspended) and the system needs to terminate it for some reason.
So this is the to go delegate method to know when the app will be terminated, either by the user or by the system, while - (void)applicationWillTerminate:(UIApplication *)application runs whenever the app goes to the background, it doesn't mean it was exitted, unless your exit means not visible

How to handle push notification when app is in background but not suspended

My app receiving push notification, and showing appropriate info message for that. However when I'm clicking to the message, application becomes active but application didFinishLaunchingWithOptions is not getting called which is right i think, since the application is not suspended and it just resigns active. The question is how i can make sure that user clicked to message when application becomes to foreground ?
I think what you are looking for is this app delegate method:
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
It will be called if your app is backgrounded, and the notification payload will be delivered in the userInfo dictionary. This contrasts with the situation when the app is launched from cold start, when this method does not get called, and instead you check in the launchOptions dictionary for the payload.
However the preferred way to do this since iOS7 is to use this:
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler;
This method is called when a user taps on a notification, regardless of whether the app is launched from cold start or foregrounded from background. So even if you are not using the completionHandler, it provides a more consistent way of accessing the notification payload. If this method is present, the older one does not get called.
If I understand the question correctly, you are asking how to be sure that the app was brought into the foreground as the result of the user “clicking” i.e. acting on a push notification.
When the app is not running at all, you can use -application:didFinishLaunchingWithOptions: as you mention. The launchOptions dictionary contains the payload, etc. — I won’t describe this since you already know how this works.
When the app IS running however, that method is not going to be called. Instead, - application:didReceiveRemoteNotification: is called. BTW this is called if the app was already in the foreground OR if it was in the background and the user “clicked” on the push notification banner/alert to open the app. It will not be called otherwise: so I believe this is exactly what you’re looking for.
The userInfo dictionary provided by this method will contain the notifications data, similarly to -application:didFinishLaunchingWithOptions: for more ad-hoc processing. (Note: userInfo and launchOptions are semantically different, but hopefully this is obvious. :))

Application force kill callback when user taps the red (-) button on the app icon

When the user force kills the iOS application I need to reset some data in my app. But according to Apple's documentation post ios SDK 4.0 applicationWillTerminate callback method does not get called and the application is killed without being notified. So I would appreciate if anyone helps me find some solution/ other way to capture the event.
You should persist your state by, in your appDelegate, implementing
- (void)applicationWillResignActive:(UIApplication *)application
This will be called when the the app is about to enter background.
Read more in the Apple documentation here
Edit
You can't know if the app is terminated by the user or the system while running in background. If you need to clean up stuff, do it when the app is launched in:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

When do I schedule local notification

When the user leaves my iOS app, I want to schedule a local notification to remind him about my app. What is a correct place to do it? I cannot choose between
- (void)applicationWillResignActive:(UIApplication *)application
and
- (void)applicationDidEnterBackground:(UIApplication *)application
Or there's no difference in the case?
I also have a second question. When my app launches (either if user pressed notification, or from launchpad), I should obviously remove all that reminding notifications. I guess I should do it in
- (void)applicationDidBecomeActive:(UIApplication *)application
or
- (void)applicationWillEnterForeground:(UIApplication *)application
or maybe another method? Or it makes no difference again?
Do it all in applicationWillEnterForeground. Remove any old notifications that don't matter now the user it engaged with the app and install any new notifications for after this use session. If the notification fires when the user is still using the app then you don't need to display anything (and the system won't display anything either).

Resources