Can I figure out in iOS whether the app is resuming from standby or from multitasking - ios

I'm currently working on a change request for our iPad app that requires that I handle the resuming of the app in two different ways depending on whether the app returned from multitasking (the user was active in another app or on the homescreen and came back to the app) and standby (the iPad was switched to standby either through the standby button on top or by closing the Smart Cover)
In both cases the following methods are called in my AppDelegate:
applicationWillResignActive followed by applicationDidEnterBackground when I hit the homebutton to get tot he home screen or close the Smart Cover
applicationWillEnterForeground and applicationDidBecomeActive when I come back.
As the same methods are called I am a bit lost on how to detect where I come from on resume. All four methods have a single parameter passing in the UIApplication. I looked at its interface, but didn't find any useful clues.
Is there a way to differentiate between resuming from multitasking or standby?

There is no public api method to define why application did become active

Related

Swift Xcode - how to differentiate between going to lock screen and going to home screen?

When the app enters the background or WillResignActive, both functions are called in my SceneDelegate. How am I able to distinguish between when the user exits the app to the HomeScreen versus just locking their phone?
EDIT: I want to perform a different function in each scenario

Will application Relaunch after app goes background

If I send my app to background by clicking the home button and wait a certain time (perhaps 1 or 2 hours).
What will happen if i tap on the app icon now?
Will the app relaunch or simply be brought from background to foreground?
Quick "prologue":
Welcome to the wonderful world of stack overflow (SO), I myself am rather new here, but found it much friendlier to use welcome you anyway!
Just in case you haven't: Before you ask a question please look around a bit on SO in case someone else has asked the same thing, but if you can't get your question answered from that, then you should of course ask your own question.
Answer:
This question has no definite answer, because it depends. When you tap the home button your app enters, as you've said, the background and is still running to a certain degree. However after done so, the apps life cycle is up to iOS (the devices operating system) to determine. iOS controls and checks memory and CPU usage (etc..) of the device, and if you start another activity while your app is in the background that makes the available memory and CPU etc of the device not sufficient, iOS will terminate any apps in the background to not waste those resources (or battery etc). If so your app will relaunch next time you tap on it.
Although if you don't do anything performance heavy it is more likely that iOS keeps your device running in the background.
I'm not sure about the exact conditions and such the iOS works on, but i would say its very likely your app will have gotten terminated and is relaunched after 1 or 2 hours "in the background". Additional conditions apply if the device is locked during that period.
For proper documentation of this i would recommend reading Apples documentation for handling App State Transitions and/or the api for UIApplicationDelegate on apples developer website. Where you can see what the different methods in the AppDelegate does and how they interact.
Edit (answer to comment):
A way to relaunch the app everytime it goes into background?
Hm, yes, but also no. I'm not 100% sure about this (never encountered that "wish" before), but you can do this in your AppDelegate: (It will basically crash your app, but beware that apple does not encourage you to crash your own app anywhere). Doing this might stop the app from passing through apple store review process (i.e. your app might not be accepted to the App Store).
func applicationDidEnterBackground(_ application: UIApplication) {
exit(0)
}
Check out the answer to these post for a bit more information: call exit(0) in iphone app , objc - Proper way to exit iPhone application?.
Personally I would recommend you to work around it and don't do this. Also remember that when your app will enter the background applicationWillResignActive will be called and when the user opens it again, applicationDidBecomeActive gets called so you can do a reload or something from there if you want to refresh any data.
Whenever we press the home button in our device, the application releases the currently being used memory and moves to background stage. However, when we press this application app icon again it brings the app on top of the iPhone screen and occupies memory again. This is definitely not the relaunch because relaunch depends upon the UIApplicationDelegate method
didFinishLaunchingWithOptions. When we are switching app from background to foreground then applicationWillEnterForeground method fires.
For better understanding, the following link might be useful
iOS Application Life Cycle

Exit from a Watchkit app is handled by the Watchkit OS itself, I don't need to clear or reset screen?

OK, this is pretty basic but I've read the documentation over and over and want to be sure I've got this right. In plain language, my watchkit app will be shut down by some user interaction exiting the app that's external to my code, right? I don't need to clear or reset the screen with any kind of close procedure that sets it up for another run? I don't need to build an "Exit" or "Close app" routine, right? It's confusing because the documentation implies the app will deactivate once it's no longer on screen (presumably by a user action like swiping to another app) and that this will call the didDeactivate function. But the documentation also claims:
In iOS Simulator, WatchKit calls the didDeactivate method for the current
interface controller when you lock the simulator by selecting Hardware > Lock.
When you subsequently unlock the simulator, WatchKit calls that interface
controller’s willActivate method again. You can use this capability to debug
your activation and deactivation code.
But the simulator doesn't appear to deallocate memory or reset variables or reset my app in any way. It remains persistent on screen in the state at the time of the lock, and it comes back in that state when I unlock. What worries me is that if I've got this wrong, I have an app built for one run. But I don't see routines for shutdown, screen clearance, or any of the elements you'd expect in a conventional shutdown routine.
I agree that the documentation can be confusing. The easiest way to think about it is that willActivate is called whenever your interface controller is displayed/activated. Likewise, didDeactivate is called whenever it is hidden/deactivated. So, if you're flipping through pages of controllers, each will receive a willActivate when it shows up and a didDeactivate when it disappears. Similarly, if a controller is deactivated because the app is no longer visible (e.g. it was suspended), didDeactivate will be called. If the user then raises their wrist to resume the app, willActivate is called, because the interface controller is being displayed.
There is no promise about whether your WatchKit app will be suspended or terminated (it's up to the OS), so you have to consider both possibilities. Based on experience, I know that dropping your arm will call didDeactivate before suspending your app. If you then raise your wrist, the app will resume and call willActivate. In my testing, the app was simply suspended (not terminated) in this situation.
You're correct that there is no built-in method that is called when the app is terminated. However, iOS 8.2 added four notifications that can be used to monitor the app/extension's state:
NSExtensionHostDidBecomeActiveNotification
NSExtensionHostDidEnterBackgroundNotification
NSExtensionHostWillEnterForegroundNotification
NSExtensionHostWillResignActiveNotification

Determine the app state on pressing home button twice with app running

I would like to know as to what the application state would be on hitting the iphone "Home" button twice with the application running.
The scenario is something like below:
My iOS app is running on the foreground
With the application running hit the home button twice to bring up the multi-tasking taskbar (obviously my app is not listed here because it's not a recently used app and is still running in the foreground)
Now press anywhere outside the taskbar (i.e in the application) and app will be back in focus again
My questions:
What state would be app be on performing above step #2? Would it enter background or still in foreground? What method would get triggered here?
On performing step #3, would the app re-enter foreground from background? Again what method would get triggered here?
Any hints/suggestions would be very helpful.
The application is about to move from active to inactive state, so it's still in-between. You should be able to use -applicationWillResignActive: in your UIApplicationDelegate.
After returning to the application, the application becomes active again thus receives a -applicationDidBecomeActive: on your UIApplicationDelegate.

How to determine an app moving to a background state due to a phone call or due to the user pressing the home button

I would like to perform a different action when my app moves to the background depending upon if its moving to that state because there is an incoming phone call, or if its moving to that state because the user has hit the home button.
In both cases the app delegate receives a willResignActive:, then a didEnterBackground: call. Therefore from the app delegate calls alone it would appear its not possible to determine the difference.
Is there some way?
UIApplicationDelegate Protocol has a variety of methods for Monitoring Application State Changes.
Unfortunately (for you), going into the background is going into the background, there is no differentiation as to why. Given Apple's app design of walling everything off (for security reasons) I don't see them providing you details about what's going on on the phone outside your application.
I would certainly question the need for different behavior in those two cases, but I don't know the details of your app.

Resources