Xamarin.iOS Apps: Adding Login/Signup Capabilities

In today’s modern mobile apps it is very common for apps to require a user account in order to function.  Apps like Twitter and Instagram require a user account in order to be used.  So a very common User Experience is to show a Login Page when the app first starts up.  The user should enter in their credentials, and then log into the app.  If the user does not have any credentials, the app should offer them the ability to create an account, and then log them in.

Though this seems like a trivial task, it can be somewhat confusing if you are new to building iOS apps using Xamarin.iOS.  In this article I’m going to show you an effective way to add a Login Page and a Signup Page to your Xamarin.iOS apps with a great user experience and a neat animation trick.

Full Source Code

You can download the full source code for this example app from my GitHub page.  I’m not going into great detail into creating each individual view controller, but I will show you the important parts step by step.

https://github.com/SharpMobileCode/LoginForiOS

Overview of the Sample App

A very common way to create user interfaces for iOS is by the use of Storyboards.  I personally don’t like to use Storyboards to create my iOS UI as they are not very user friendly when it comes to sharing cross-platform code with Xamarin.Android apps.  But storyboards are a very popular way to create user interfaces for Xamarin.iOS.  Here is a high level overview of the sample app.

SampleAppStoryboard

MainStoryboard.storyboard

From the image above we can see that this application utilizes a UITabBarController controller as the Initial Root View Controller.  The UITabBarController is the main page the user is directed to after they successfully log into the app.  The UITabBarController also has two Tabs that are encapsulated by two UINavigationControllers.  This allows subsequent pages to be pushed onto the Navigation Stack, such as the Tab 1 View Controller.

In MainStoryboard.storyboard, you can also see a LoginPageViewController as well as a SignUpViewController.  You can see that there is no direct way get to the LoginPageViewController or the SignupViewController from your UITabBarController.  This is done intentionally as we will show the LoginPageViewController programmatically.  But fist, let’s discuss the most important parts in detail.

LoginPageViewController

The LoginPageViewController consists of two UITextFields.  One for the Username, and the other for the Password.  In addition, we have two UIButtons.  One button is to log into the app, and the other is for showing the user the Sign Up page so they can create an account.  Now let’s take a look at the codebehind for LoginPageViewController.cs

The first thing to note is we create an Event called OnLoginSuccess.  When the user taps on the “Login” button, the app will validate the user name and password.  If validation is successful, then we will fire the OnLoginSuccess Event.  Notice here that we want to keep this Login page loosely coupled and we fire an event after we successfully authenticate our user.

This ViewController will leave it up to another client to do whatever it wants after we authenticate our user.  This gives us the flexibility to show different View Controllers after we log in.  For example, if we have two different storyboards, one for iPhones, and the other for iPads, this gives us the flexibility to show either ViewController/Storyboard without tightly coupling our Login Page to another View Controller.  The LoginPageViewController doesn’t, and shouldn’t care what it should show next.  That should be decided else where.

The Application Delegate

In order to show the LoginPage, we need to make some modifications to our AppDelegate.cs file.  Remember, the AppDelegate is created for every Xamarin.iOS Project, and is the root object of your application.  When you create a Xamarin.iOS Storyboard application, the AppDelegate is automatically created, and will launch your MainStoryboard.storyboard InitialViewController (as set in the storyboard).

UITabBarController-Properties

UITabBarController Properties. Set StoryboardID and as Intial View Controller.

The first thing we add is a private property called isAuthenticated.  This is actually optional, but if you want add AutoLogin capability, this is one way or doing it.  I don’t keep track if the user is automatically logged in this app.  So I just set this to false for simplicity.  If you need this capability, you would need a way to store a flag if the user wants to automatically log in every time they start the app.

The second thing we need to add is a public property called MainStoryboard.  This property will programmatically return an instance our our MainStoryboard.storyboard file.  We are going to call this several times since all of our UIViewControllers are defined in MainStoryboard.storyboard.

The third thing we need to add is a public method called GetViewController().  From the code above you can see that GetViewController() has two parameters.  The first parameter is an instance of the Storyboard where our ViewController is defined.  The second parameter is the name of the ViewController (aka StoryboardID) we want to instantiate.   With these two parameters, we can return an instance of any ViewController that is defined in the given Storyboard.  Remember to set the StoryboardID for each ViewController you want to dynamically instantiate.

LoginPageViewController-Properties

Remember to set your Storyboard ID for each UIViewController.

 

The fourth thing we need to add is a public method called SetRootViewController().  SetRootViewController() requires two parameters.  The first parameter is an instance of our new RootViewController.  The second parameter is a boolean value.  If true is passed in, when we animate a transition when we change the RootViewController of our app.  If false, no animation occurs.  Also note the transition type.  I set it to UIViewAnimationOptions.TransitionFlipFromRight as it creates cool looking flip effect from right to left.  But you can set it to any transition type you want.  Just choose another enumeration from UIViewAnimationOptions.

The fifth and final thing we need to do is override the FinishedLaunching method().  This method will execute after the application has finished launching, and is ready to display our initial view controller.  By default, this method is not overriden, and will load the ViewController that is set as the “Initial View Controller” in MainStoryboard.storyboard.  But in this case, we want to dynamically set our RootViewController to our LoginPageViewController if our user is not already authenticated (i.e. Auto-Login is not enabled).  If our user is already authenticated (i.e. Auto-Login is enabled) we want to set our RootViewController to our UITabBarController.

You’ll also notice when we create an instance of the LoginPageViewController, we also wire an event for the OnLoginSuccess event (remember we defined this earlier).  So in our event handler, we want to create an instance of our UITabBarController, and set it as the application RootViewController.

So, when the application start up, we programmatically determine if we want to show the login page or not by setting the RootViewController of the application.  You’ll notice that we pass in false as the animation boolean parameter for SetRootViewController().  Animation isn’t necessary when we start up.  But for the OnLoginSuccess event handler, it is nice to have a cool animation effect when the user taps on the Login Button.

Logging Out

After you start the app, tap on the second tab on the UITabBar.  This will show the TabPage2ViewController.  On that view controller, you’ll see a log out button.  This is a simple implementation, but can bind this to anything you want, include a button on the Navigation Bar or a slide out menu option.

So now that we’ve defined all of our logic in our AppDelegate to instantiate our view controllers and to set the RootViewController of our application, we want to do this outside our AppDelegate.  When the user taps on the Logout Button, we need to set the application RootViewController back to our Login Page.

Looking at the code above, we get a reference to our Application Delegate.  Since the AppDelegate is a Singleton, there is no need to create an instance.  We just need to get the current reference from our UIApplication.  Second we get an instance of our MainStoryboard.storyboard from our app delegate.  From that we can create a new instance of the LoginPageViewController, set the OnLoginSuccess event handler, and then set it as our new RootViewController.  Notice in this case when we call SetRootViewController(), we pass in true, for our animation effect (pretty cool looking isn’t it?).

Signing Up For An Account

So now the user has been logged out of our app and we see the Login page.  If you tap on the “Signup” button, this will create an instance of the Signup View Controller.  If you look at the code behind for SignUpViewController, you will see pretty much the same pattern.

The pattern is the same as the logout implementation.  We just get a reference to our app delegate, instantiate the proper ViewController, and then set it as our RootViewController.

Summary

In this article I showed you an effective way to show a user a login page by swapping the application RootViewController.  In addition, I also showed you how to add an optional animation effect when you set the app RootViewController.  This enhances the user experience, and makes the transition less “jaggy”.  We implemented all of this login in the AppDelegate.cs file, and we referenced the AppDelegate in other parts of the app.

I hope you found this useful and feel free to leave me a comment below with any questions.  And download the source code and feel free to dissect the code and play around with it.

  • Pingback: Ruben Macias: Xamarin.iOS Apps: Adding Login/Signup Capabilities | XamGeek.com()

  • Pingback: Adam J Wolf: Weekly Xamarin Newsletter Issue #37 | XamGeek.com()

  • Christian Hinostroza

    Thank you so much for this tutorial it really has been incredibly helpful, I am however wondering if you could help me out . I am trying to instantiate the View Controller as you described in this tutorial, but I continue to get a thrown exception “Exception has been thrown by the target of an invocation.” at return storyboard.InstantiateViewController (viewControllerName);.
    The only different thing I did was to create a navigation controller with a root to the view controller that has my login View Controller , but i also tried removing the navigation controller since i did some research and I found the navigation controller somehow does not get added to the layers before you call the root. Anyways that did not work hopefully you could give me some insight. Thanks

    • A TargetInvocationException is a general exception that is a wrapper for the actual exception that caused the problem. The InnerException property contains the actual exception that was thrown. Look at the InnerException property for the Exception Message and Stack Trace. If need be, feel free to create a sample project that re-creates the issue and post it up on Stackoverflow or the Xamarin Forums and post the link to it here.

  • Awesome work and tremendously helpful. I built this out but ran into one simple error. On line 15 of your AppDelegate file you call “MainStroyBoard”; for me this throws a run time error unless I change it to simple say “Main” to comply with the default name of the storyboard. Beyond that runs perfect.

    • Glad to hear you found this article useful! Yes, if you name your storyboard “Main”, as this is the default when you create a Xamarin.iOS project, then you’ll have to use “Main”. I however created a blank project from scratch (without the wizard), and thus named my storyboard “MainStoryboard”. But yeah, you’ll have to modify that string to whatever your storyboard name is.

  • Ahmed_IT

    Thank you for your amazing tutorial. But how to make it work using UISplitViewController
    I tried it but faced issue with Navigation controller when navigating from login to UISplitViewController Master/Detail.

  • agrumiro

    I always obtain follow error “Warning: observer object was not disposed manually with Dispose()”, any idea?

  • sharedOne

    HI, first of all great website / blogs (bookmarked your page!) 2nd: I’m pretty new to mobile development and to using Xamarine, before this I did a bit of IOS development. I’m finding it hard to find documentation on what should be placed where exactly for cross platform development. For instance the login / signup example above, If I wanted to create this for Xamarin.Android and Xamarin.Ios what code can I reuse and how should I structure that? Do you know of any documentation / tutorials that explains this? This is probably not the brightest question, but any help would be really appreciated.

  • Justin Van Bibber

    This is awesome, and is exactly what I need for my App… One issue, though: It would appear as though there have been some changes to how xamarin works since this post. For example – GetViewController now requires: UIKit.UIApplication, a string array, and an NSCoder? I would love to see an update to this post that includes these changes. I’m stumped and documentation is so scarce! Thanks a million!!

  • Ravalesh

    Thanks a lot..I was struggling with the logout functionality in my app which uses a side bar Nav plugin. I used this approach. Works like a charm :)