App workflow of iOS app - ios

I am making an app with 2 navigation controllers in storyboard. 1st one is LoginRootController and 2nd is RootController.
LoginRootController is set as the initial view controller. I have google and facebook login integrated to the app. Their delegates are in AppDelegate. When I login, I set RootController as rootViewController which has the home page. I'm setting this from loginButton() of FBSDK and "signIn(signIn: didSignInForUser user: withError error:)" google delegate function. There is signInSilently() and fb sign in in applicationDidBecomeActive.
The problem is that whenever signIn is called, my home page is loaded. I want to load home page only once when I login manually. What is the optimal way to do this?

I understand that you want to avoid reloading the RootController after a silent sign in triggered by the application becoming active.
The easy option is to check the current rootViewController. If it's already the RootController, no need to change it. Otherwise, change it.
Note that you probably want to save the user ID that was used to load the RootController. If that changes, you probably need to force reloading it even if it's already there.
If that's not what you want, you'll need to be more explicit and provide the relevant parts of your code.

Related

Swift Xcode Switching between View Controllers - Navigation between View Controllers

I'm using Firebase in my app, and every time user launches the app - I need to check if the person is logged in. And if the user is logged in - I need the Home View Controller to be opened, if the user isn't logged in - I need to open the Log In View Controller. How do I implement it in my mobile app?
You can go through the Firebase Documentation, and if you see carefully enough, there is a function to get the current user email ID and the custom ID allocated to the user by FireBase. If these 2 parameters are nil when you start up your app(in your first screen), then you can performSegue(xx,yy). else you can directly go to the home screen.
You can use Boolean User Default in your app to keep track if user has already logged in before. If true then you can navigate to Home View controller else navigate to Log in view controller. You can find more details on User Defaults Here and Here

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: programmatically ask for Game Center sign-in?

I have a simple question, but I’ve looked through Apple’s documentation and done some searching and I can’t find the answer to it.
Is it possible to programmatically pull up Game Center’s sign-in view? I have a UIButton that requires Game Center, and if the client does not sign in when the app is opened (iOS pulls up the sign-in view at launch), I want to provide a second chance for the user to sign in.
I'm assuming you're calling this GKLocalPlayer method on launch: -setAuthenticateHandler: (>= iOS7) or -authenticateWithCompletionHandler: (<= iOS6)
If the user cancels the presented login screen, calling these methods again does nothing, or rather, the completion handler is called with an error. The user will then need to login to GameCenter through the GameCenter app or through the Settings app. (While testing, you can login through the GameCenter app, then logout. After that the screen can be presented in your own app again.) You can show an UIAlertView telling the user to login through the GameCenter app.
Alternatively, and I don't know if this is allowed/approvable, but in iOS7 the authenticateHandler has a viewController parameter holding the login screen. If you store this login view controller in an instance variable and the user cancels login, you can present the login screen again later using a UINavigationController.
If you try to present the saved login view controller with -presentViewController:animated:completion: the view controller's Cancel button no longer works, but using a UINavigationController hides the Cancel button and allows navigation back to your own view controller.
You'll also need to hide the login screen manually after the user logs in by responding to GKPlayerAuthenticationDidChangeNotificationName. It doesn't seem like developers were intended to be able to do this, so it may not pass approval, but it works!

Programmatically logout in iOS application

My iOS application contains login page. And after entering the app there is a logout button. When a user presses the logout button programmatically I want to show login page again as if the user is logging first time. Could you please suggest how I could implement this in my iPad application.
I do this in my app. I have a tabbarcontroller that i use for logged in users. When they log out (or for first time use) I message the appDelegate that removes the tab bar from the window and makes the login view the root view. Once logged in, that view is replaced by the tab bar controller.
I even go a bit further. On each switch I totally release all the other objects, and so I know for sure that when user sees any of these views it's completely 'fresh' and only uses the defaults for anything custom to that user.

Resources