iOS UIManagedDocument closing - ios

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.

Related

iOS app returns to rootViewController when kept in background

My iOS app returns back to rootViewController when kept in background for longer time.
To demonstrate I have the below picture
I navigate all the way to ViewControllerC and keeps the app in background, when I returns to the app say after 30 mins, the app shows rootViewController i.e. ViewControllerA.
I want it to remain on ViewControllerC as it stays in Whatsapp. I know that my app (idle apps) will be removed from the memory when system falls short in memory, so when I open the app it will take me back to the initial View controller specified. But then why this doesn't happen with whatsapp?
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

Save UIViewController and display again if needed

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

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?

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 Reset/Restart Application from UIButton

I have a simple iOS app that I am developing that needs to be "restarted" or "reset" after a user performs a certain touch action and a "reset" button appears. The workflow of the app goes something like this:
User holds a certain area of the screen
User lets go of the screen and quickly touches another area
The time it took for them to let go and touch the next area is displayed in a UILabel.
A reset button appears in which the user presses to try again.
Steps 1-3 work perfectly, but currently the only way I have to "reset" the app is to exit with the home button, open the multi-tasking menu and manually close it and re-open it.
I know this has to be able to be done as I 've seen it in many apps. I just can't find much help with the developer docs on it.
Thanks!
You can kill the app with a call to abort(). There's no way to start it after you killed it, though.
Perhaps you can schedule a local notification before killing the app that prompts the user to open it again.
You should probably just create a method that resets all of your variables and then calls the methods that begin steps 1-3. To have the button appear, make a UIButton IBOutlet to attach to the reset button, and then hide it in viewWillAppear like this:
[myButton setHidden:true];
To then show the button later, use the same button but set the value to false instead of true.
You could try removing your view controller from the application window and releasing it then instantiating a new instance of that view controller and adding the new instance to the window as the root view controller.
Since I'm assuming your view controller is where most of your "setup" code for your app is occurring this should effectively reset the app without having to write a lot of extra code. In addition, having the ability to instantiate a new instance of your view controller class is kinda the point of having it to begin with.
You can sleep your application for specified time interval.
+ (void)sleepForTimeInterval:(NSTimeInterval)ti
or
+ (void)sleepUntilDate:(NSDate *)aDate
Methods is works for you
Please refer NSThread class Documentation

Resources