Save UIViewController and display again if needed - ios

I am trying to create a system where a user can open a UIViewController, close out of that ViewController, and return to the same ViewController if they closed it by accident. The UIViewController is populated with data from the internet (that changes frequently) and is a long scrolling UITableView. Currently when the user enters the same UIViewController again, the data is lost and must be re-downloaded, and their previous position is lost.
On the Android version of my app, I have a ViewPager as the main view, with the main pane being the left Fragment and the opened pane as the right Fragment. When the user opens the same "submission", the Fragment is not re-created and the user returns to the same screen, and if the user clicks a new submission, the old Fragment is deleted and a new one is loaded in its place. This allows for the state to be the same and the user can go back if they closed out of the pane by accident.
I think keeping a static version of the UIViewController would be bad practice and lead to memory issues down the road, but I cannot think of another way to implement this. Any suggestions would be appreciated.

You should read up on Apple's docs on restoring view controller state: https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/PreservingandRestoringState.html
Additionally, you will need to archive and unarchive the data being displayed in your view controller. Therefore you might want to implement the NSCoding protocol in your model classes. Once you've implemented NSCoder, you can use NSKeyedArchiver / NSKeyedUnarchiver to save and restore state for your view controller. Read up on NSCoding here: https://developer.apple.com/reference/foundation/nscoding
Finally the App Delegate sends out notifications when your app is about to terminate or move to the background. So in this class you will need to start the whole process of saving and restoring application state. Read up on UIApplicationDelegate here: https://developer.apple.com/reference/uikit/uiapplicationdelegate

Related

Starts with specific scene when App launch from background iOS

I wonder how to launch the App from background with specific scene instead of always starts with launch screen or main.storyboard's initial ViewController.
For Example, if the user was viewing the profile scene and then make the app go to background from there, I would like to launch the same profile scene(without reloading or the profile pictures, bio, etc) the next time the user bring the app to the foreground.
Now the case is that the App always start with the launch screen and or the information that was loaded before went away.
How can I remember the specific scene when App enters background? By the way, I noticed this issue when I refractored the storyboard.
That's exactly what state restoration is for!
State restoration is a feature in iOS that lets a user return to their app in the exact state in which they left it – regardless of what’s happened behind the scenes.
You can enable it from your appDelegate by overriding application:shouldSaveApplicationState: and application:shouldRestoreApplicationState:
and having them returning true.
Then you will have to apply restorationIdentifier to your viewControllers (and yes, you can do it from the storyboard :) ). Doing so will allow your user to come back to the very screen / screen hierarchy they were when they last left...
You will however have to handle the logic the the data that need be displayed. In your viewController subclass, you can override encodeRestorableStateWithCoder: and decodeRestorableStateWithCoder: to store and then retrieve your data to display from the coder.
find the Apple doc here : https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/PreservingandRestoringState.html
And a Ray Wenderlich (love the man!) here : https://www.raywenderlich.com/117471/state-restoration-tutorial

applicationDidBecomeActive keep logged in similar to instagram

What I'm looking for is a mechanism to keep my app from resetting to the root view controller every time the application gets backgrounded or goes inactive. There are many apps out there that operate this way, namely Instagram, eBay, etc.
My instincts told me initially to poke into the AppDelegate's applicationWillEnterForeground method, where I would try to present the viewcontroller I'm after, however when I instantiate the viewController, I can present it, but without the navigation controller that normally be there.
This makes me think that I need to save the "state" of the application (maybe the NavigationController's stack?) and then restore the stack somehow when it gets relaunched.
I have watched the execution timings of each event and notice that closing the application and relaunching it will start the application fresh. I assume that my NSUserDefaults are still in place and thus could be checked for a logged in user. This could help determine which view in the navigation controller to push to (either login or dashboard).
Any direction is greatly appreciated.
The most revealing answer in this post was the use of some storage (NSUserDefaults) in order to store persistent data across uses.
For my specific case, this was storing a key holding user info. Then when the application loads, the would-be first view comes up, but if that key is missing, will modally pull a login view in front of it.
To do this I would use NSUserDefaults to store the current view of the app and then switch to that view when your app finishes launching. See the answers to this question: Swift: How to store user preferences?

Loading the last View Controller Active after app goes into background, swift

I have "Tinder" like swipping view that is located in a CardViewController. The card View Controller is accessed by moving through two other view controllers. i.e. Load App -> FirstViewController -> SecondViewController - > CardViewController.
When I am in the Card ViewController and I go into background mode, the app launches on the FirstViewController and on going to the cards, they are loaded from the first card in a stack of about 10?
Is there anyway to load the app from the last Card I had swipped and in the CardViewController without having to navigate from the FirstView Controller again?
I would really appreciate the help as it's horribly affecting some of my users.
An example of a Tinder like card view is shown!
The problem, from the sound of it, is not what happens when the app goes into the background — that would leave it in exactly the same state when it reactivates. The problem is what happens when the app goes into the background and quits. Your app is then relaunched from scratch, which is why you find yourself in the first view controller. What's upsetting you is the difference between the app's behavior in these two situations.
Apple provides a solution to this situation: UIViewController, along with the App Delegate, has methods permitting you to save and restore state. When the app goes into the background, the current configuration (what view controller's view is showing) is saved. That way, even when the app quits, when it relaunches it can get back to that configuration before it appears to the user. Thus, coming back from background-and-quit looks just like coming back from mere backgrounding.
For full details, see Apple's documentation. This is a good place to start:
https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/PreservingandRestoringState.html

IOS initial view controller based on condition retrieved from database

An iOS app I'm creating shows a setup screen upon first launch which requires data to be written to the database.
Upon launch, I need to access this value form the database.
If it is set, launch main view controller
Else show setup view controller.
As far as I'm aware theres two ways I can do this, programmatically setting it from the AppDelegate or using an initial View Controller as a splash screen and performing the look up and segue there.
What would be the best way to approach this? Is it wrong to do a database lookup in didFinishLaunchingWithOptions?
Using a splash screen is probably the better option as it provides better scope for modification in the future and allows you to update the user on progress. It is fine for the app delegate to run logic to determine how the app starts but you should endeavour to keep the app delegate minimal and focussed.
I very much doubt that you would get this approved (if your goal is the App Store). Your app delegate needs to create a window, and set a rootViewController to that window before it returns YES in appFinishLaunching:
You simply do not have enough time to check with a server before creating the first viewController and you'll be creating poor interface if you try. I suggest the first ViewController will need to be informing the user that it is checking with the server with an activityIndicator or something. The best :)

iOS UIManagedDocument closing

Unless done explicitly, is the only time a UIManagedDocument closed when the app is "quit"? By quit I mean when the user double taps the home button and holds onto the apps and closes them out.
I ask because right now I have my app in a tabBarController and I'm using the tabBarController to handle all the UIManagedDocuments since every other view controller has access to it via self.tabBarController. Right now my tabBarController will check if the UImanagedDocuments exist, are in a closed state, or are in an open state and deals with it accordingly to yield an open document ready to use. I'm doing this in viewWillAppear. I noticed that viewWillAppear for a tabBarController is only called once in the lifetime of the app before it is "quit". So I'm wondering if I need my other view controllers to check if the UIManagedDocuments they use are open before they use them or can I assume they will remain open until the app is "quit" if I don't explicitly close them anywhere in my code?
I have not seen this behavior where the UIManagedDocument closes when the application loses focus. I do believe you have to close the document explicitly if you want it closed. But to know for sure you can sign up for the UIDocumentStateChangedNotification and see exactly when it goes into a closed state.

Resources