Xamarin.Forms: Solving Navigation and Appearance Problems

I have spent the better part of the last few weeks building my Score Predict app in Xamarin.Forms.  After much emphasis by Xamarin at their Evolve event in 2014 I wanted to get a sense as to how ready Forms was for primetime, especially with the recent 1.3 release.

Sadly, while there are many positives with Forms, certain features are weird or just not developed enough for me to give the platform a full vote of confidence and make me choose to use it over more mature approaches such as those involving MVVMCross.  Let’s look at a couple:

Appearance

The idea for Forms, conceptually, is very ambitious: unify the definition of the UI and allow each platform to translate that definition into a native user interface.  Achieving this would effectively negate the single biggest weakness of “one and done” platforms like Titanium and PhoneGap, which is allowing a single UI but creating one that follows the idioms of the target platform.

For the most part Forms nails this pretty well.  Where you mainly run into issues is when applying a custom theme, but most of this can be solved with custom renders or by leveraging the abilities of the platform as in the case of Android.

However, it is clear the team is still not sure what do on at least one element in iOS: the toolbar.  This concept is fairly straightforward in Android (Action Bar) and Windows Phone (Application Bar), but is less clear on iOS which has limited space in the Navigation bar.  At this point the team has settled on the concept of primary and secondary navigation.

On Windows Phone and Android, Primary will make the action available outside the overflow until the space is consumed.  Secondary places the item directly into the overflow (application menu on WP and the pop out on Android).  On iOS though you have two options: specify both as primary and get this:

Use Secondary and you get this:

Honestly, between the two the former is the better looking, but not by much.  I dont recall ever seeing an iOS app putting two links in the upper right or left.  Generally, you get only two buttons with the left primarily be used for navigation.

There actually is a precedent for handling this scenario is iOS, the toolbar.  This was established in iOS7 and has become an integral part of many of Apple’s own apps, such as Maps:

image

It seems like this would be the preferred way forward, or at least allow the usage of the left hand side of the navigation bar.

It also seems like you cannot Custom Render the TabbedPage interface.  I was trying to after this to fix Android which looked like this:

image

Despite defining a Custom renderer for TabbedRenderer I could not get a reference to the TabWidget or the TabBar.  The only way I found to correct this was to visit http://jgilfelt.github.io/android-actionbarstylegenerator/ which allowed me to create a Style that I could apply to the MainActivity responsible for launching the application.

[Activity(Label = "Score Predict", MainLauncher = true, Icon = "@drawable/app_icon", Theme="@style/Theme.Maintheme")]
public class MainActivity : FormsApplicationActivity, IPageHelper
{

Kind of weird, since one would think I should be able to do this via the Custom Rendering engine.  Here is a link to the styles as generated by the website: https://gist.github.com/xximjasonxx/d5a8f36f9631e8ff0141

Navigation

On the topic of navigation, this is not done well in Xamarin.Forms and for Forms to be successful its going to have to be done better since Navigation is one of the core elements in a successful experience.  However, one has to undertake significant effort to support even the most standard user flow in Android and Windows Phone.

Consider a simple app with a login function that fronts the main app.  It is fairly standard paradigm where the user must login before being granted access to the app.  Here is the story for each of the platforms:

iOS
The user should launch the app and if no valid authentication information is available the user should be placed on the Login screen with access to a create login screen.  Upon successful login or registration the user should be placed into the app with no way back to the login screen without invoking a logout function.

When the user launches the app and valid authentication information is available, the user is immediately placed on the main page.

Android & Windows Phone
The user should launch the app and if no valid authentication information is available, the user should be placed on the login screen.  Pressing the hardware back button should cause the user to leave the app.  Successful login or registration should place the user on main page.  From this page, if the back button is pressed the user leaves the app.

The user should have no way to reach the login screen without invoking the Logout function.  If the user launches the app with valid credentials, they are immediately placed into the main page.

Forms provides the Navigation property to all ContentPage instances as a means to abstractly control navigation.  Primarily you will find Push* and Pop* methods for control navigation.  The issue is two things: 1) the presence of the back button on Windows Phone and Android and 2) the different way iOS presents things versus Android and Windows Phone.

The bottom line is the way navigation is presented to the user is very different on a per platform bases.  For example, iOS will make heavy use of modals because developers can completely control when the modal gets dismissed.  In Android and WP, developers must be more careful due to the presence of the hardware back button.

WP and Android users will expect the Back button to do different things based on the screen, therefore successful apps must take this into account.  Some may point out that you could override the Back button to suppress it or change its behavior, but this is not at all recommended by any platform guidelines (further, I have not found a way to suppress it as returning false in the override does nothing).

The best way around this that I have found is to leverage Dependency Injection to enable navigation (especially at the start) to be handled differently depending the platform.  To that end, I defined the IStartupPageHelper and IPageHelper interfaces.  Since each platform defines its dependencies through injection I can ensure the appropriate implementations are used per platform.  For iOS I defined the MainPageWithModalStartupHelper to assist with determine the startup page.  Here is the source:

    public class MainPageWithModalStartupPageHelper : IStartupPageHelper
    {
        #region IGetMainPage implementation

        public Xamarin.Forms.Page GetLoginPage()
        {
            var mainPage = GetMainPage();
            mainPage.Navigation.PushModalAsync(PageFactory.GetLoginPage(), true);

            return mainPage;
        }

        public Xamarin.Forms.Page GetMainPage()
        {
            return PageFactory.GetHomePage();
        }

        public Xamarin.Forms.Page GetUsernamePage(User user)
        {
            var mainPage = GetMainPage();
            mainPage.Navigation.PushModalAsync(PageFactory.GetUsernamePage(user));

            return mainPage;
        }

        #endregion
    }

As you can see, iOS views the MainPage as its root, regardless of the user state.  However, if we want to display the Login or Username pages, we display them as modals.

On Windows Phone and Android we use StandardStartupPageHelper

    public class StandardStartupPageHelper : IStartupPageHelper
    {
        #region IStartupPageHelper implementation

        public Xamarin.Forms.Page GetMainPage()
        {
            return PageFactory.GetHomePage();
        }

        public Xamarin.Forms.Page GetLoginPage()
        {
            return PageFactory.GetLoginPage();
        }

        public Xamarin.Forms.Page GetUsernamePage(User user)
        {
            return PageFactory.GetUsernamePage(user);
        }

        #endregion
    }

This is much simpler because we are simply displaying the page as the root.

Once we have our startup page the user will either attempt to login or create a user; this is done within a NavigationPage component so as to provide navigation to iOS and Android (Windows Phone doesnt have anything like this).  Once we are ready to return to the MainPage we invoke methods on our IPageHelper implementation.  This is where things get very interesting.  On iOS it looks like this:

    public class TouchPageHelper : IPageHelper
    {
        private INavigation Navigation
        {
            get { return Resolver.CurrentResolver.GetInstance(); }
        }

        #region IPageHelper implementation

        public void ShowLogin()
        {
            Navigation.PushModalAsync(PageFactory.GetLoginPage(), true);
        }

        public void ShowMain()
        {
            Navigation.PopModalAsync(true);
        }

        #endregion
    }

I should point out that my code is rolling a custom DI implementation that I wrote; my plan is to move to Autofac in the near future.

iOS is pretty straightforward.  To show the Login screen we “Push” that page onto the stack as a modal.  To return to Main we “Pop” the modal.  In fact, this class is located in my Core project and is not platform specific.

On Android, my attempts to modify navigation stack did not end well and I stumbled across this bit of code (pre 1.3) to physically change the root page of the application:

    public class MainActivity : FormsApplicationActivity, IPageHelper
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            Forms.Init(this, bundle);

            LoadApplication(new App(new StandardStartupPageHelper(),
                new ServiceInjectionModule(), new DroidInjectionModule(this)));
        }

        public void ShowLogin()
        {
            SetPage(PageFactory.GetLoginPage());
        }

        public void ShowMain()
        {
            SetPage(PageFactory.GetHomePage());
        }
    }

As you can see, we are actually implementing this interface on the Launcher activity for our app.  This, so we can make calls to Obsoleted “SetPage” which resets the root of the application.  Calling this method will change the root of the application and allow us to exit the application if the Back button is pressed since this will become the first page in the stack.

Now, you may be expecting to see a similar implementation for Windows Phone and you would be wrong.  There may be a way to do something similar but my attempts to call ConvertToUiElement ended in failure.  However, on Windows Phone navigation is tracked globally, so we can actually manipulate the stack.  Here is the implementation of IPageHelper on Windows Phone; located in the Core project using Forms code:

    public class PhonePageHelper : IPageHelper
    {
        private INavigation NavigationProperty
        {
            get { return Resolver.CurrentResolver.GetInstance(); }
        }

        /* dont use the PageFactory - no navigation controller concept in Windows Phone */

        public void ShowLogin()
        {
            NavigationProperty.PushAsync(new LoginPage());
            ClearStackTo();
        }

        public void ShowMain()
        {
            NavigationProperty.PushAsync(new MainPage());
            ClearStackTo();
        }

        private void ClearStackTo() where T : Page
        {
            var stack = NavigationProperty.NavigationStack;
            if (stack.Count > 1)
            {
                var page = stack.First();
                if (page.GetType() == typeof (NavigationPage))
                    page = ((NavigationPage) page).CurrentPage;

                var typesMatch = page.GetType() == typeof(T);

                while (!typesMatch)
                {
                    NavigationProperty.RemovePage(page);

                    page = stack.FirstOrDefault();
                    if (page == null)
                        throw new InvalidOperationException("Could not find the requested page");

                    if (page is NavigationPage)
                        page = ((NavigationPage) page).CurrentPage;

                    typesMatch = page.GetType() == typeof(T);
                }
            }
        }
    }

Here is what is happening.  Whenever ShowLogin or ShowMain is called we will “Push” that page onto the stack.  This places the instance of this page at the end of our stack.  We will then Clear all pages from the stack up to that type.

Notice also that I do not use my PageFactory here.  The reason is the page is currently inside a NavigationPage which is located at the root, despite Windows Phone not rendering anything for this.  Attempting to return another NavigationPage (which is what PageFactory is returning) will cause an error due to more than one Root element being present.  The solution here is to simple new up the page without the NavigationPage.

As a side note, in the IPageHelper example you will see my extracting an INavigation dependency.  That is simply the Navigation reference given to the root page, assigned in my App class constructor:

        public App(IStartupPageHelper getPageHelper, params InjectionModule[] modules)
        {
            Resolver.CurrentResolver.Initialize(modules);

            _readUserSecurityService = Resolver.CurrentResolver.Get();
            SetMainPage(getPageHelper);

            Resolver.CurrentResolver.AddModule(new CoreInjectionModule(MainPage.Navigation));
        }

Closing

Let’s be honest.  The Forms team has only made this available for about a year and the progress has been immense.  It would be insane to expect such an endeavor to be perfected so quickly.  As a concept, I absolutely love Forms (and the ability to use Xaml for iOS).  Score Predict is so far along after 3wks I want to jump on this tool and use it for my next client.  However, as a consultant I can see they’re are some very rough edges that must be smoothed out, least of which is the Navigation.

Remember, the goal of Forms was to enable the creation of apps through a unified UI definition that gets translated into a native app from Xaml or code.  This approach enables the developer to have a minimal understanding of the platforms to quickly create an App in a language they understand.  In reality, the developer continues to need intimate knowledge of each platform to “plug the holes” present in Forms (Appearance and Navigation in this case).

I must admit that it is possible there are better ways to do some of the things above; if so, it is not well-known since my searching turned up nothing other than just how important a solid understanding of DI is for Cross Platform Mobile Development.

I look forward to what the team delivers in future releases and hope they stay on track cause this is really something I would love to succeed cause it is truly an awesome remarkable concept.

Full source for this project is available here: https://github.com/xximjasonxx/ScorePredictForms

The case for Xamarin Forms

When I first got exposure to Xamarin.Forms at Xamarin Evolve I was a bit skeptical.  I always figured that one of the great strengths of Xamarin was the specific UIs it allowed you to create allowing the app to fit with the design of the targeted platform.  This, in my opinion, gave it a huge advantage over HTML5 which would often require a single UI for all platforms.  So, I was curious why Xamarin had opted to pursue a strategy which would forfeit this advantage, or so I thought.

It turns out Xamarin has found a means to share even more code without compromising its ability to provide platform centric UIs.  Granted, right now, Forms, is primarily targeted at Line of Business apps where the UI can be generalized across the platforms.  Apps that require a heavily customized UI are best left to use vanilla Xamarin.

Forms works by defining a central Core project which contains the all important App class that defines app lifecyle handling and the start page.  Each supported platform has a separate project that references the Core project’s App class.  Within the Core project we define our pages, usually using Xaml, and define navigation between them.

When the app is run, the Xaml is turned into either ViewControllers, Activities, or PhoneApplicationPages by Forms.  This is done by using Renderers which look at the elements used in the Xaml and output the appropriate control for that element.  For example:

The Entry control represents a editable textfield which is supported in all platforms.  When the iOS version of the application is run the EntryRenderer will take this and create a UITextField from it.  Similarly, it will create an EditText on Android and a TextBox on Windows Phone.

In addition, developers are free to create their own renderers to alter controls as they see fit, both native and custom.  These renderers are implemented within the platform specific project and exported to the main system.  A full introduction to their usage can be found here: http://developer.xamarin.com/guides/cross-platform/xamarin-forms/custom-renderer/

Score Predict

One of my personal side projects is Score Predict which is a game that allows users to predict the scores of football games and get points depending on how close they are.  I originally spent most of last year writing this in native iOS and Android.  It was beyond painful and left me with no time or energy to support Windows Phone.  In addition, it became impossible to add new features because it would take me weeks to develop the feature for the other platform.  So I decided to use Xamarin.Forms.

The results have been incredible.  Within two weeks, I have completed 30% of the app in Android, iOS, and Windows Phone.  The app looks incredible (big thanks to my brother @brandclay for the new logo) and adding new features is a simple update that affects all three platforms.  This even puts me ahead of MVVMCross because I dont have to create the UI for the feature more than once.

Furthermore, I have found limited cases where I have to do something platform specific.  Mainly it has been the addition of a title to pages on Windows Phone because it doesnt support a navigation bar, and customizing the text colors for the Entry fields for each platform so they match the theme.

Keep in mind that the UI for Score Predict is relatively simple and falls within the apps that Xamarin.Forms makes sense for.  If this was an app requiring heavier amounts of customization I would probably gone back to vanilla Xamarin with MVVMCross.

Xamarin.Forms: The App in 1.3

One of my goals for the New Year is to learn Xamarin.Forms well enough that I can begin doing some serious speaking on it.  To that end, I decided to rewrite my Score Predict personal project app using it; this would give me a sense as to maturity of the platform and its viability in future projects both personally and professionally.

My experience got off to a rocky start as I seemed to have caught Forms in the midst of upgrading to 1.3.  I had quite the struggle getting things to work.  With the help of Xamarin’s Jason Smith I was able to overcome my difficulties which really amounted to synching my NuGet package versions and updating the project file.

The biggest difference I have found so far in 1.3 is the way the App class is defined.  Before we saw things like this:

public class App
{
    public static Page GetMainPage()
    {
        return new ContentPage
        {
            Content = new Label
            {
                Text = "Hello, Forms !",
                VerticalOptions = LayoutOptions.CenterAndExpand,
                HorizontalOptions = LayoutOptions.CenterAndExpand,
            },
        };
    }
}

This would then be called by platform specific code to load in the page.  Here is an example:

    [Activity(Label = "Main Page", MainLauncher = true : AndroidActivity
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            Xamarin.Forms.Forms.Init(this, bundle);

            SetPage(App.GetMainPage());
        }
    }

You can see here, the reference to a static method which really seems incorrect given the features of C# and what .NET allows us to do.  Additionally, this sort of approach requires the developer understand the existing infrastructure of the target platform; which may not be desirable.  All in all, while this works but it could be done a lot better, I feel. The Xamarin guys thought so as well.

The new way utilizes a Forms specific base class for the platform specific launcher.  This base class provides a method LoadApplication which takes an instance of the custom App class and understands what that means for starting the application.  Here is an example of what your App class looks like in 1.3:

	public class App : Application
    {
		public App()
		{
			MainPage = new SplashPage ();
		}

		protected override void OnStart ()
		{
			base.OnStart ();
		}
    }

You can see the App class inherits from Application which is a new Forms specific class.  This class now allows you to override methods pertaining to the app’s lifecycle for the various platforms, including access to the Properties property which is a property bag that will take care of serialization of values for state persistence.

The main goal of the Application class, in addition to handling lifecycle events, the Application class also specifies to the MainPage which is what each platform will look at when loading the first page in the application, in this case the first page is SplashPage.

In order to load this appropriately, you need to call Forms.Init() and LoadApplication() in each platform like so:

iOS (AppDelegate)
    [Register("AppDelegate")]
    public partial class AppDelegate : FormsApplicationDelegate
    {
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            Forms.Init();
            LoadApplication (new App ());

			return base.FinishedLaunching (app, options);
        }
    }

One thing I will point out is, I noticed that it helps of you call the base FinishedLaunching method otherwise iOS seems to get confused.  This might be something Xamarin will fix in the near future.

Android (MainActivity)
    [Activity(Label = "ScorePredict", MainLauncher = true]
	public class MainActivity : FormsApplicationActivity
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            Xamarin.Forms.Forms.Init(this, bundle);
			LoadApplication(new App());
        }
    }

Windows Phone (MainPage)

    public partial class MainPage : FormsApplicationPage
    {
        public MainPage()
        {
            InitializeComponent();

            Forms.Init();
            LoadApplication(new ScorePredict.App());
        }
    }

Overall, the change using a base class and for each platforms launching mechanism hides a lot of code and enables developers to really focus on what their application does, not how it starts.  I love the new approach and I see a lot of potential with this platform for the majority of apps for platforms.  Already, as I write this, I am working on a new version of my Score Predict app and, because I am taking this approach, I am basically doing all three platforms at the same time.

Once we are able to add in IoC and MVVM this is going to be the preferred way, for me, to develop applications in Xamarin, pending a custom UI that can be generalized of course.

Cheers.

Efficient Script Loading with AngularJS

Lately I have been putting my efforts towards creating a web front end for my Anime Information API.  To sharpen my skills, I decided to use Angular and really try to push things to develop good practices for organizing large amounts of JavaScript.  Central to this is, separating code into different files to ease maintenance.  But this resulted in this:

image

Having to add a tag each time a new file was added is painful.  Not only that its horribly inefficient, this approach will load code that the user may never even execute, so its a waste.

Luckily, this problem exists outside of AngularJS and has been addressed in many different ways, the most common way is through the AMD style loading supporting through libraries like RequireJS.  RequireJS allows to define our modules in terms of their implementation and the dependencies of that implementation.  It then takes care of managing scripts, including downloading those which are not yet downloaded.

This does result in some additional code being added to our code files and a bit of a learning curve to understand how we must organize AngularJS to allow RequireJS to work.  Frankly, it is very surprising that this sort of functionality isnt already built into AngularJS.  If it is, I could not find evidence of this, and the presence of the AngularJS RequireJS seed project would indicate I am not the only one who could find no dynamic script loading in AngularJS.

Setting Up

So, the idea with RequireJS is we can define our scripts as an application.  So, with RequireJS all of the lines above should be reduced to:

image

Pretty neat eh? But getting here isn’t easy.  The seed project can help, but I already have an existing solution to try to integrate this in.  With this line RequireJS will look for the main.js file in the app folder, this file will define the definitions needed by RequireJS.  Here is the contents of that file.

require.config({
 paths: {
  bootstrap: '../scripts/bootstrap',
  angular: 'scripts/angular/angular.min',
  angularRoute: 'scripts/angular/angular-route.min',
  uiBootstrap: 'scripts/ui-bootstrap-tpls-0.11.2.min',
  text: '../scripts/requirejs/text',
  underscore: '../scripts/underscore-min'
 },
 shim: {
  'bootstrap': ['jquery'],
  'angular': { 'exports': 'angular' },
  'angularRoute': ['angular'],
  'uiBootstrap': ['angular', 'bootstrap'],
  'underscore': { 'exports': '_' }
 }
});

//http://code.angularjs.org/1.2.1/docs/guide/bootstrap#overview_deferred-bootstrap
window.name = "NG_DEFER_BOOTSTRAP!";

require(['angular', 'app', 'routes'], function(angular, app, routes) {
 var $html = angular.element(document.getElementsByTagName('html')[0]);

 angular.element().ready(function() {
  angular.resumeBootstrap([app['name']]);
 });
});

I removed some of the definitions to make this shorter.  What you need to know is the paths section defines the scripts to be used while the shim section allows you to define dependencies between those script files (example: bootstrap require jquery be loaded).  In addition, most scripts are not written to be AMD complaint, thus for those we can define what the script exports which can be used within RequireJS.  An example of this is the angular object used within AngularJS apps.

Once you understand this the top section above becomes fairly self explanatory.  The next section is a bit tricky as it defines your bootstrap for RequireJS, or what gets run first.  To understand this, look at the three values in the JS array fed to require.

  • angular – this matches the name from the shim section, so RequireJS will ensure the file indicated in the paths section is loaded
  • app – since there is no shim configuration for this, RequireJS will attempt to load app.js in the same folder as main.js.  You could use directories here if you like, such as ‘code/app’ would attempt to look, from the level of main.js for app.js in the directory ‘code’.
  • routes – same as above.  Looks for routes.js

So now, the code hands off control to the familiar app.js that we see so often with Angular apps.  Here is the full contents of the file:

define([
    'angular',
    'views/controllers',
    'repository',
    'services',
    'filter',
    'angularRoute',
    'uiBootstrap'
    ], function (angular, controllers, repos) {
        return angular.module('animeApp', [
            'ngRoute',
            'animeApp.controllers',
            'animeApp.repositories',
            'animeApp.services',
            'animeApp.filters',
            'ui.bootstrap'
        ]);
});

RequireJS will attempt to match the name of the dependencies to those listed in the shim configuration, in this case angular, angularRoute, and uiBootstrap.  The other dependencies will be looked up based on the path to the JS file.

The interesting part of this comes in the callback.  We setup the module configuration for Angular as normal.  This pattern will be pervasive throughout the remainder of this.  We use define to ensure the scripts containing the bits needed are loaded.  Within the function we roll our Angular as normal.  We will see more examples of this later.

Lets’s look at the filter.js file to see this in action:

define(['angular', 'angularSanitize', 'angularUnderscore', 'repository'], function(ng) {
 return ng.module('animeApp.filters', ['ngSanitize', 'underscore'])
  .filter('termHighlight', ['$sce', function($sce) {
      return function(input, term) {
          var regex = new RegExp("(" + term + ")", "ig");
          return $sce.trustAsHtml(input.replace(regex, "<b class='highlight'>$1"));
      }
  }])
  .filter('filterCategoriesBySettings', ['_', 'settings.repository', function(_, settingsRepo) {
      return function(categories) {
       if (categories === undefined || categories.length == 0)
        return [];

          var showHentai = settingsRepo.getShowAdult();
          return _.filter(categories, function(category) {
              return category.isHentai === showHentai;
          });
      }
  }]);
});

Now, if we look at the define call you can see references to the shim configuration (angularSanitize, angularUnderscore), we also references repository.js which ensures we can use settings.repository in the Angular code.

This strategy is applicable to your controllers, services, and other modules of the application.  Of course, the major problem with doing this is you end up with all of your controllers/services/filters/etc in the same file.  This, to me, deviates from the goal of Angular, which is to break apart files so you dont have these massive JS files.  Our goal needs to be to further this approach, but maintain the file separation that Angular makes so easy.  That will be in part 2.

Dependency Injection and the Web

Lately I have been tasked with fixing a couple projects for clients where they were experiencing sporadic and unexplainable errors.  In both cases, I was shocked that previous developers had not taken the time and care to properly manage critical objects within the web application.

The big reason why Dependency Injection has gained such prominence among web developers is that it allows us to easily manage these objects from a central configuration without convoluting our code or require overloads.  And as with most frameworks, we can take advantage of functionality that is difficult to implement on our own.

The biggest advantage is the support of “web scoping”, that is we can scope objects to work well on the web.  Often this means providing at least the following three scope levels:

  • Application
  • Session
  • Request

This is in addition to runtime scoping levels offered by most DI frameworks, usually:

  • Singleton
  • Transient
  • Thread

The difference is, while the runtime scoping is useful, we have to remember that web applications are inherently multi-threaded, so a singleton will get shared by all users, similar to using the “Application” type web scope.

Probably the most important web scope is “request” since its often the best choice for those critical objects whose usage and scope mean the most to us, i.e. the database context (EF) or Session (NHibernate).  I find that getting support for this web scope has been at the core of the last two projects I have worked on at West Monroe.  The essence of this scope, is the object is resolved only one time per request.  This is ideal for databases where keeping the connection open too long is not good as is opening a new connection each time we talk to the database; its a healthy middle.

I think Dependency Injection is a very important aspect of modern development, if only because it pushes you to build applications from smaller decoupled blocks of code that are easier to test and reuse.  The fact that we can tightly control the scope of objects, both in a runtime and web context sense, is extremely useful and saves me from having to write and test that code myself.

There are MANY frameworks available and depending on your circumstances you should choose the one that fits best.  For example, one client project is using Spring .NET which isnt even supported and considered archaic by most standards.  Another, newer, project didnt even have Dependency Injection was constantly throwing sporadic errors from different areas.  We wanted to use AutoFac (which is a newer framework) but due to the use of ASMX web services in the backend process (for which AutoFac support is questionable) we opted to use Ninject.  For most of my side projects, I use AutoFac because its newer and supports many of the concepts that have made DI much easier since its inception.

I have also used StructureMap, Unity, and Castle Windsor in the past, so I am fortunate to have a wide experience with DI.  I think developers should focus on understanding the strengths and weaknesses of each of these tools, it helps you to make the right decision.  A great example of this is, the client using Spring .NET, we debated replacing Spring with Autofac.  We ended up staying with Spring so as to not add an additional variable into an already tumultuous situation.  Good thing to because we would find out about the support for Autofac with regard to ASMX.

Fixing Azure Mobile Services

Recently Windows Azure had a nearly global problem with its Azure Storage system which resulted in real downtime for many services, see here.  This affected one of my personal projects that was in development, basically even after the fix was made I was not able to access any of my endpoints.

To correct this, I performed a fresh publish ensuring the option to remove files at the destination was checked.  This succeeded in restoring the service and I thought everything was fine.  However, over the next couple of weeks I noticed some issues with updating the service, however I lacked the time to fully dive into the problem.

I finally got time around Thanksgiving as I was grounded for the week from traveling.  The main problem was that any new changes to the code would not show up on the server, that is I would get 404s for my new endpoints.  At first, I thought this was a routing issues since I was using custom routes for the new endpoints.  However, when I updated an accessible endpoint to return “Hello World” I got the original result, which confirmed to me that it was not a routing issue (all of this code worked locally) but instead a problem updating the code.

Even after continued efforts to re-publish with the removal of destination files, no change was seen.  So, I downloaded the Publish profile from the website, imported it and extracted the FTP server, username, and password and plugged that in the FileZilla.  I then attempted to remove everything from my wwwroot and repository directories.  I figured this would bring the service down and allow me to forcibly push the right DLLs; it did not.

Even with all files removed, I was able to hit the endpoints I knew still worked.  Even when I published to those empty directories, I still got the old result.  Thus, the only path I had left for me was to delete my service and recreate it with the same name.

I had to be very careful doing this because I did not want A) to delete my database and B) I wanted the new service to utilize the same schema name in the SQL Azure Database.  Thankfully, this approach worked and the service is back online and I can confirm new changes are working properly.  This also had the side effect of fixing the problem with my connection string that I noticed a few months ago.

Speaking with MVPs and Azure team members, no one seems able to explain what exactly happened or why those DLLs would not update.  My guess is that the storage mechanism behind the scenes had to change in response to the outage so my old service was likely located in a bad area, but with recreation is now located in a good area.

Hopefully, I can get some clarity on what happened.  In the meantime, I hope this helps anyone who is having issues the same as me.  Though, I realize deleting the service and recreating it is not a fun option

Hijacking Mobile Service Authentication

Recently, while developing Score Predict I ran into a snafu where my iOS version was rejected by the Apple AppStore.  There were two reasons for this rejection; one of the reasons was not surprising, the other one, however, was.  According to Apple, if I chose to rely exclusively on Facebook authentication, I had to use my granted FB access for something else in addition to authentication; a lesson I had to learn.  This effectively met I could either speed up the timeline and implement the FB capable features.  This would mean pulling the Android version (which had already been approved) and likely cost me the entire football season.  So I opted to create a supplemental manual login for Facebook only.

The principle issue was, I was relying on the generated Facebook username, given to me by mobile services, as a means to link data together.  In addition, I had already implemented user level authentication on the sensitive services and I did not want to provide non-social endpoints for the manual users.  So what to do?

Well as I looked at what makes the client authenticated, I realized it was the combination of a generated user Id and what I came to learn was a JWT (JSON Web Token) token, I previously referred to this as a Zumo token.  In addition, it is widely known that you can give the client a pre created token from a social provider to be used.  So I summarized that the same could likely be said for the Auth token.  If I could create it myself, I could likely get Azure Mobile Services to use it and the two logins types could use the same endpoints.

To begin with this, I knew I would need to determine how I might create a JWT token.  Lucky for me, I stumbled across this article: http://www.thejoyofcode.com/Generating_your_own_ZUMO_auth_token_Day_8_.aspx

In reality, all this is a simple hashing algorithm where the salt is unknown to the under user, this is what allows the security to exist, being signed by the Master Key.  For my project I created the following NodeJS module to house this logic:

// require external node modules
var crypto = require("crypto");

// actual node module
module.exports = {
    createZumoToken: function(expiryDate, aud, userId, masterKey) {
        function base64(input) {
            return new Buffer(input, 'utf8').toString('base64');
        }

        function urlFriendly(input) {
            return input.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');
        }

        function sign(input) {
            var key = crypto.createHash('sha256').update(masterKey + "JWTSig").digest('binary');
            var str = crypto.createHmac('sha256', key).update(input).digest('base64');
            return urlFriendly(str);
        }

        var s1 = '{"alg":"HS256","typ":"JWT","kid":0}';
        var j2 = {
            "exp":expiryDate.valueOf() / 1000,
            "iss":"urn:microsoft:windows-azure:zumo",
            "ver":2,
            "aud":aud,
            "uid":userId
        };

        var s2 = JSON.stringify(j2);
        var b1 = urlFriendly(base64(s1));
        var b2 = urlFriendly(base64(s2));
        var b3 = sign(b1 + "." + b2);

        return [b1,b2,b3].join(".");
    }
};

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Then it gets down to it, it is very straightforward.  It relies on the crypto library which is included as part of the overall Node setup you are given for every Mobile Service JS backend project.

In terms of usage, following the creation of the user, that is after the record has been inserted, I simply create the token and add it to the response (below):

var expiry = new Date().setUTCDate(new Date().getUTCDate() + 30);
var aud = "";
var master = "";
var token = jwt.createZumoToken(expiry, aud, user.id, master);

complete({ id: user.id, token: token });

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

I have yet to understand how the validation of these tokens works, what it is looking at because, aside from the Master Key, the aud is not stored anywhere.  However, this appears to work, so for right now, that is enough.

To utilize this is no different than if you were working with Facebook.  Below is some Objective-C code which handles the response to the create_user endpoint.

-(void)handleSuccessfulUserCreateWithData:(NSDictionary *)data {
    // get the values from the data
    NSString *userId = [data objectForKey:@"id"];
    NSString *token = [data objectForKey:@"token"];
    
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setValue:userId forKey:@"UserId"];
    [defaults setValue:token forKey:@"Token"];
    [defaults synchronize];
    
    [self goToMainView];
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

You can see that we are simply storing the values as normal in the User Defaults.  They are then accessed through our getClient method from the ClientFactory class (below):

+ (MSClient *)getClient {
    NSURL *url = [NSURL URLWithString:@"https://scorepredict.azure-mobile.net"];
    MSClient *client = [MSClient clientWithApplicationURL:url
                                           applicationKey:@""];

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if ([defaults objectForKey:@"UserId"] != nil && [defaults objectForKey:@"Token"] != nil) {
        NSString *userId = [defaults stringForKey:@"UserId"];
        NSString *token = [defaults stringForKey:@"Token"];

        MSUser *user = [[MSUser alloc] initWithUserId:userId];
        user.mobileServiceAuthenticationToken = token;
        client.currentUser = user;
    }

    return client;
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

This is all the same for both the manual and Facebook calls, thus the service works regardless of which login method is used.  The difference in the two is the UserId transmitted, which will be the generated Facebook username for the Facebook calls, but a randomly generated Guid for the manual calls.  This being the case, I ensured that a string is used to store the user associated with the data, thus joining is agnostic to this difference.

In reality, we are not really hijacking the login system, we are simply performing some impersonation.  I am still looking at the overall security of the Mobile Service with this approach, however, I feel that as long as the Master Key is kept secret, there should be little chance of a compromise.

New York City Code Camp 2014

I recently spoke at the 2014 version of the New York City Code Camp, my talk was focused on the Modern Trend in Software Development towards Services and the “Connected Experience”.  The event was also something of a reunion for me as it allowed me to reconnect with many of the friends I made when I worked on Long Island from 2009-10.

The content of the talk is largely geared at helping developers to understand, conceptually, where things are going and how services can help us target the immense number of platforms available: platforms such as TVs, Cars, Appliances, Consoles and others in addition to the well known tablet and smart phone platforms.

The talk does not delve too much into the technical aspects of this because I believe that in doing so you imply a “silver bullet” path for achieving a separation between application and data.  There is no such thing, the key thing is to understand why there should be a separation before the how.  For this reason, I showcase many tools and concepts to underscore the point I am making, including a brief look at AngularJS as an example of how easy it can be to create a “client”.

Overall the event went well, very impressed with how much it has grown since the early days when I first attended in 2010.  600 people attended and I had at least 50 people in my talk, standing room; something I was not expecting.  I am now more invigorated than ever to give the talk in St. Louis and, hopefully, CodeMash.

Spending some time in NYC was great and it is amazing how my perception of the city has changed with my living in Chicago; I definitely see things much different.  Anxious to get back to things in Chicago.  My next speaking engagement will be internally at West Monroe Partners on the topic of Cross Platform Mobile Development using Xamarin and MVVMCross, where I am going to show off a Proxy Twitter app.

Implementing a Sliding Menu in iOS

As mobile apps become more and more complex, there is an ever increasing need to handle more complex navigation structures. The prevailing paradigm is the hamburger menu, which is usually displayed use either a button or right swipe, this is also referred to as a sliding menu. So popular this design strategy has become that Android made it a native control with the Navigation Drawer control. Implementing it in iOS is more complicated, but well worth it.

Do it yourself? Or download one

I have seen people implement this effect with great success but usually it follows a tremendous amount of effort. My recommendation is to use a library to achieve this effect. CocoaPods makes integrating a third party library extremely easy. If you search for “iOS Sliding Menu” in Google, you will find MANY sliding menu libraries, a testament to the popularity of this approach. For this tutorial we will be using ECSlidingViewController: https://github.com/ECSlidingViewController/ECSlidingViewController
Installing this couldn’t be easier. First create your project in Xcode. Our application will be a Single View Application. SingleView Note: I am currently using the Beta version of Xcode 6. My target for this app will be iOS 7
Once the application is fully setup, close Xcode and open a Terminal window. cd to the project directory and create a file called ‘Podfile‘. The contents of this file should resemble the image below: Podfile Note: Podfile is part of the Cocoa Pods dependency management system. This file dictates the dependencies of an application
Once you save the file, return to the terminal and run the following command: ‘pod install
Note: if you get a command not found it means Cocoa Pods is not installed. To install run the command: ‘sudo gem install cocoapods’
If this also does not work, I suggest referencing cocoapods.org for a complete installation.

Once the installation completes you will be instructed to open your app using the .xcworkspace file instead of .xcodeproj. Please be sure to do this as the workspace will ensure your pod dependencies are properly linked into your projects.

The Setup

The setup in this application is going to consist of a principal (root) view, two content views, and a menu. Below indicates the parent class for each:

  • InitViewController : ECSlidingViewController
  • MainViewController : UIViewController
  • SecondViewController : UIViewController
  • MenuTableViewController : UITableViewController

One of the great resources I had in learning this library was YouTube and Kyle Begeman tutorial series on this library: https://www.youtube.com/watch?v=tJJMyzdB9uI. However, the version he is using is out of date. The new version relies on the use of User Defined Keys for the initial view in the storyboard.
Here is a shot of all of my views laid out on the storyboard: Storyboard layout
The key thing here is check the Identity Inspector for InitViewController, below: Init withKeys There are two user defined keys here:

  • topViewControllerStoryboardId
  • underLeftViewControllerStoryboardId

topViewControllerStoryboardId indicates the Id of the view on the storyboard which will represent the “top” content, or the initial content that will be shown. underLeftViewControllerStoryboardId indicates the Id on the storyboard which represents the left under view, this is the menu. In our example, MainViewController defines a StoryboardId for itself (on the Identity Inspector) of Main and MenuTableViewController defines a StoryboardId for itself of Menu. These are defined here to define the initial setup. There are many more keys which can be defined, see here.
Be sure to check the Use StoryboardId checkbox
If you run the application now within the Simulator, you will see your initial view, but you will not be able to access the menu. We will add those bits next.

Getting the Menu to open and slide

Go to the MenuTableViewController file and add the following method implementation and corresponding header file entry: Menu controller
This method will be responsible for “unwinding” the menu slide segue which you will add in the next step.
Switch back to the Storyboard and add a UIButton to each subservient view (Main and Second). It can be placed wherever you like. Next, select the “Exit” icon for the View Controller (below): View exit
Note: this icon may be green in your version of Xcode
With the “Exit” icon selected, Ctrl-Click and drag the unwindToMenuViewController action to the newly created UIButton. Below is a screen shot with the “Connections Inspector” visible and the Menu button selected. Connection inspector
Running the application now, will allow you to open the Menu by clicking the button. However, we are left without a way to close the menu and our menu items will not take us anywhere. Let us fix that.

Setting up Advanced Interaction

One of the big things missing is the ability to pan the sliding menu. It is very common for the user to be able to “drag” the menu from the side to reveal it, along with having a button. To accomplish this, we must add a Pan Gesture. This gesture is associated with each subservient view controller; it is added within the viewDidLoad method. Sliding gesture
Note: This line of code must be added to each view in which you want the user to be able to slide the menu out. I recommend a base class
Note: To ensure that slidingViewController is a valid property you will have to import the “UIViewController+ECSlidingViewController.h” file
If you execute the application now you should be able to drag the menu out by swiping from the left screen edge toward the right edge. You can even drag it back to hide the menu. Pretty cool.

Adding Navigation

The last bit of this is to add a sliding segue to support navigation between the menu items and their corresponding views. To this, select the appropriate Table View Cell and Ctrl-Click drag to the appropriate View Controller. When you release select the sliding option (below): Sliding segue
Run the application and you should be able to navigate and show off your new sliding menu.

Conclusion

I have always find these kind of pull out side navigation very helpful for more involved applications. There are just certain limitations to tabs and a need for a different approach to navigation. I hope this was helpful, please let me know if anything didn’t work. The complete code can be downloaded here: https://dl.dropboxusercontent.com/u/13029365/SlideMenuTest.zip. Remember to open the .xcworkspace file.

Cocoa Pods for iOS Development

One of the great advantages .NET developers enjoy is managed package management and integration with NuGet. Thanks to Cocoa Pods this same functionality is available in iOS through Xcode. CocoaPods enables most iOS and OSX libraries to be configured as dependencies and downloaded into your Xcode project without unnecessary steps for integration and configuration.

Installing Cocoa Pods

Installing Cocoa Pods is extremely easy and is done through Ruby Gems. Simply type the following at the OSX command line:
sudo gem install cocoa pods

At the completion of this command you will be able to utilize the pod command. Hold off for now.

Using Cocoa Pods

Unlike NuGet Cocoa Pods is not yet integrated into Xcode so most of it must be done external. The first step is to create your project as you would normally. This is to give you the directory to using the pod command in. For the remainder of this example, we will refer to our app as MyApp.

Within the root of the project directory (the same level as the .xcodeproj file) perform the following command:
touch Podfile

This file governs what Cocoa Pods will install, right up to the version of the dependency. Below is a sample file which enables the installation of the JSONModel and APLSlideMenu libraries:

  target 'MyApp' do
  pod 'JSONModel'
  pod 'APLSlideMenu'

  end

Not specifying a version will cause the latest version to be downloaded.

To actually install these libraries, run the following command
pod install

Once this command completes your Xcode project will be updated. However, it is important to understand how Cocoa Pods alters the structure of your Xcode project to enable this integration. It will create a separate project for itself and require that this project be referenced by the main project.

As with Eclipse, Xcode can operate on a single projects or a group of projects within a workspace. If you check the project directory following the pod install you will find a .xcworkspace file. This is the file you will open to modify the project moving forward.

Additional information on Cocoa Pods (and the full listing of available pods) can be found here: http://cocoapods.org/.