The Codemash Solution

As the number of smartphone users who can consume data continues to increase we are constantly seeing an ever an increasing number of industries that are putting there data out there for consumption.  A few years ago, Codemash, one of the biggest conferences in the country, was among the first computer conferences, that I know of, to do this.  They exposed REST feeds and challenged attendees the create applications for conference goers.  Since then, most, if not all, conferences seem to be doing this in one way or another.

While the idea has been a huge hit, it is not without its problems.  For one thing, conferences like Codemash always seem to tax the internet (both cellular and LAN) to the point that it tinkers with being unusable.  It is also a known fact that conferences undergo session changes during their course.  This meant that a REST feed was being updated.  In general, there was no way to let app users know of these changes, without redownloading the session list.  As you can imagine, with the Internet already being slow this amounted to the app being nearly worthless next to a provided book (I noticed this at DevLink).

My idea, create an infrastructure to record these changes into “changesets” and push a notification to the user.  I figured if I took advantage of Push the user would not have to actively engage in looking for changes, but could be told when they existed.  The Codemash Windows Phone apps are the first version of this system that I hope to expand out much further, provided it is successful at Codemash.

The Poller

One of the things that was essential with this solution was the ability for changes to be recorded.  Since I didnt want the user checking because of slow Internet or (in the case of a background task) heavy battery consumption, I felt this should be done somewhere else, and what better place than in the Cloud with Azure.

I devised a single worker role which, every 30m, queries the REST API for Codemash Sessions and Speakers and compares the data with the existing data.  It then updates the existing data, creates a changeset for the changes, and then pushes a notification out to registered clients.  The clients must store their client type, so the notifications can be appropriately structured (Win8 vs WP8 vs WP7).

To make this easy, and eventually support Apple and Android clients, I utilized Ninject to inject the appropriate notification manager class depending on the client type.  This allows me to continually support new clients without changing my Poller.

The API

Codemash has its own API which will always be the most up to date.  My cloud server also contains its only local copy of the Codemash data which is kept in sync for new clients as they register.  This ensures that new clients arent not behind in terms of the state of their data.  The API is responsible for handling registration and change querying.  To get changes, the app merely sends a request (along with its client identifier) to the Change controller.  The API users this identifier to ascertain what the last confirmed changeset the client received was and if there are any new ones, if there are new ones, they are sent to the client for processing.

The Apps

So now we come to the apps, the most crucial pieces in this process.  I had a few issues that I wanted to make sure I overcame, otherwise the apps would not achieve what I wanted them to achieve.  I even ended up scrapping the Windows 8 client so that I could ensure the Phone apps were solid.

The biggest rule for the apps was to ensure that they queried as little as possible and that when a query that could take time happens it does so in a way that would still allow the app to load quickly.  The goal is to give the user the quickest startup time so that the app can legitimately replace the book.  With this in mind, there is only one mandatory blocking internet call, and that is the initial populations.  Beyond that, the only querying done is for changes, which is done each time, but done once the app has loaded so as not to inhibit the UI experience.

With this mind, after the initial call all session and speaker data is stored locally and updated locally as changes are brought done.  When changes are brought down they are applied and the user has the option to view those changes.  The result is an app that, after the first run, can start in under one second and with the initial screen aimed at displaying what sessions are next and what sessions the user has favorited.

This means that when the network is clogged at Codemash, the app will still open up quickly and let the user browse sessions without needing to download anything.

Conclusion

Having written an app in the past for Codemash, and more recently for DevLink, it is clear to me that one of the problems is the lack of consistency in the data provided.  For example, the DevLink sessions provided a unique session and speaker identifier values which made things easy.  However, Codemash does not provide such a value, so I had to resort to hashing the session title to generate the identifying value.  As you can imagine, this is going to easily break if the session title every changes.

What really need to be created is a common service which can allow conference planners to put their session and speaker information into a common database.  This way the data is consistent for conferences and the ability to reuse data is provided, this feature has many advantages.  This would allow us to define a common schema for JSON and XML for consuming clients.

Caliburn Micro for Windows 8 Apps

I am a huge proponent of the MVVM (Model View ViewModel) pattern and try to use it whenever I can.  For the web its Knockout, for client devices its Caliburn.Micro, a framework that I have come to adore and be essential in my development.  Thus it follows naturally that I would want to use it in the Codemash Windows 8 application.  The only problem, right now, is the installation is not exactly straightforward and there is no NuGet package, though one is in the works I am told.

Installation

As I said, at the time of this writing, no NuGet package or download was available for the RT version.  I am told Rob (creator of Caliburn.Micro) is encountering a licensing problem for the package.  So until that is resolved, download the source code here and build it locally.  This will produce three DLLs that you will need to include in your project:

  • Caliburn.Micro.dll
  • Caliburn.Micro.Extensions.dll
  • Windows.Interactivity.dll

Make sure all three of these files are included in your solution and referenced in the appropriate projects.  These DLLs are compiled in such a way as to support both ARM and x86 compilation targets.

Configuration

I use CM a lot when developing Windows Phone 7 applications, and in that respect you have to write a Bootstrapper class to configure your injection container and apply any custom contentions.  Unfortunately, my injection container of choice, Ninject, either does not work in WinRT or I cant get it to compile locally.  One of the problems with using a new OS is many popular libs are in the experimental stage.  So in this case, eliminate all code in the App.xaml.cs file and perform the configuration there.  Rob was nice enough to provide the WinRTContainer class which can suffice for basic injection scenarios.  It does not support Property Injection, which is something I love in Ninject, but it is adequate. Here is the code comprising my configuration:

        protected override void Configure()
        {
            base.Configure();
            _container = new WinRTContainer(RootFrame);
            _container.RegisterWinRTServices();

            // repositories
            _container.RegisterSingleton(typeof(ISessionRepository), null,
                   typeof(JsonSessionRepository));
            _container.RegisterSingleton(typeof(ISpeakerRepository), null,
                   typeof(JsonSpeakerRepository));

            // custom support components
            _container.RegisterInstance(typeof(IAppService), null,
                   new CodemashApplicationService(RootFrame));
        }

        protected override object GetInstance(Type service, string key)
        {
            return _container.GetInstance(service, key);
        }

        protected override IEnumerable<object> GetAllInstances(Type service)
        {
            return _container.GetAllInstances(service);
        }

        protected override void BuildUp(object instance)
        {
            _container.BuildUp(instance);
        }

.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; }

To define the starting point, or the first ViewModel which should be loaded by Caliburn Micro, override the GetDefaultViewModel method, like below:

        protected override Type GetDefaultViewModel()
        {
            return typeof (SplashViewModel);
        }

.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; }

Quick note: This method is only available if you are inheriting from CaliburnApplication.  Best way to do that is in the App.xaml file, below:

<caliburn:CaliburnApplication
    x:Class="Codemash.Client.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:caliburn="using:Caliburn.Micro">

  

</caliburn:CaliburnApplication>

.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; }

At this point your application will load your Default View Model (SplashViewModel in this case).  Remember the convention based approach.  SplashViewModel loads the SplashView.

Usage

As I started earlier, the WinRTContainer, provided by Caliburn.Micro, does not support Property Injection, so all injection is done through the constructor.  There are some standard ones that WinRTContainer provides automatically.  Perhaps most important of these is the INavigationService which allows you to navigate to different view models, thereby loading different views.  For example:

     public void ViewMap()
     {
         NavigationService.NavigateToViewModel();
     }

.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; }

In addition, you can pass parameters when you navigate, this allows you pass things like selected items to a detail view.  This part is a bit funky and differs from what we see in the WinPhone 7 implementation.  The recommended approach is define a Parameter type object to encapsulate the value, or values, you want to pass.  Example.

        public void SessionClick(ItemClickEventArgs args)
        {
            var listItem = (SessionView) args.ClickedItem;
            if (listItem.SessionId != 0)
            {
                var session = SessionRepository.Get(listItem.SessionId);
                NavigationService.NavigateToViewModel(
                   new SessionParameter(session));
            }
        }

.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; }

In order to receive this parameter, you must create a property on the corresponding view model (SessionDetailViewModel in this case) named Parameter.  During the navigation process, WinRTContainer will look for this property and inject the parameter value into it.  Example:

public class SessionsListViewModel : ViewModelBase
{
        // parameter
        public GroupingParameter Parameter { get; set; }

       // additional code
}

.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; }

Handing Interactive Events

One of my favorite aspects Caliburn.Micro is the configuration for handling events in custom ways.  Using the Windows.Interactivity library, you can augment the standard event handling mechanism within CM with the event arguments, like this:

        <ListView SelectionMode="None" IsItemClickEnabled="True"
                        ItemTemplate="{StaticResource SessionItemTemplate}">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="ItemClick">
                    <cal:ActionMessage MethodName="SessionClick">
                        <cal:Parameter Value="$eventArgs" />
                    </cal:ActionMessage>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </ListView>

.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; }

.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; }

Further information on special parameter passing can be found here.

Deploying to Surface for Debugging

So one of he major goals I had with purchasing a Surface was to deploy the Windows 8 Codemash application so I can see how it looks.  At first I thought I would need some combination of USB cables.  As it turns out, you can do this over your network using some tools.

Tim Heuer explains how to do this here:

http://timheuer.com/blog/archive/2012/10/26/remote-debugging-windows-store-apps-on-surface-arm-devices.aspx

Biggest thing to remember is right now since only the RT version is out at this time, its ARM based so when you deploy make sure you are compiling to the ARM architecture.  When the x86 version comes out you can use traditional deployment.

Happy Debugging

Snapping in Windows 8 Apps

One of the decisions that Microsoft made with Windows 8 is to support the concept of “snapping”.  This allows the user to have two applications running on the screen at one time and is one of the features with distinguishes Windows 8 from its competitors.  This gives a unique experience for the user and adds to productivity.  However, it does add another dimension for the develop to consider when creating applications.  But Microsoft makes it pretty easy to handle.

Windows Resizing

Changes in window size are nothing new in applications for any platform and the trend has been rather constant to expand the size (or density) of mobile form factor screens in recent years.  Just as we had to deal with screen size change when the tablet was introduced, and subsequently had to adjust when Apple unveiled the Retina display, now we adjust to understand apps can run in different sizes.
In Windows 8 the display modes are Snapped, Fill, Full.  Snapped is when the application window is “snapped” to the right or left in something of a sidebar look. The Fill state occurs when one application is snapped, the other is said to “fill” the remaining portion of the screen.  Finally, Full, is when the application has the window to itself and is the default running mode for RT applications.

Handling the Size Change

Handling this change is pretty easy.  The approach I took was to define a base class called LayoutAwarePage.  Note that, VS2012 templates do provide this same class with a similar implmentation.  In fact, it was in studying these default templates that I was able to learn the most about “snapping”.  Whenever the Windows Size changes, the SizeChanged event fires.  Within this event handler access the ApplicationView.Value value, this will contain a string representation of the mode (Snapped, Full, Filled).  This will give you a clear indication as to which display mode you are in.  Here is my abstract base class, LayoutAwarePage:

public class LayoutAwarePage : Page
    {
        protected LayoutAwarePage()
        {
            if (Windows.ApplicationModel.DesignMode.DesignModeEnabled) return;
            SizeChanged += OnSizeChanged;
        }

        private void OnSizeChanged(object sender, SizeChangedEventArgs args)
        {
            // get the view type
            var displayType = ApplicationView.Value.ToString().AsDisplayType();

            // call our handler
            HandleLayoutChange(displayType);
        }

        protected virtual void HandleLayoutChange(DisplayModeType displayType)
        {
            return;
        }
    }

.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; }

The HandleLayoutChange method is virtual so that each page can override it, thus allowing that page to customize how it handles the changing layout.  Based on examination of the default templates, I would say Microsoft is recommended developers use Visual States to handle this. I havent been able to get mine to work just yet, so I have dropped back to talking to the control directly, bit of a deviation from MVVM that I love, example:

public sealed partial class MainView : LayoutAwarePage
    {
        public MainView()
        {
            this.InitializeComponent();
        }

        protected override void HandleLayoutChange(DisplayModeType displayType)
        {
            FilledGridView.Visibility = Visibility.Visible;
            SnappedListView.Visibility = Visibility.Collapsed;
            PageTitle.Style = (Style) App.Current.Resources["PageTitle"];
            PageTitle.Margin = new Thickness(20,0,0,7);
            AppBar.Visibility = Visibility.Visible;

            if (displayType == DisplayModeType.Snapped)
            {
                FilledGridView.Visibility = Visibility.Collapsed;
                SnappedListView.Visibility = Visibility.Visible;
                PageTitle.Style = (Style) App.Current.Resources["SnappedPageTitle"];
                PageTitle.Margin = new Thickness(10, 0, 0, 7);
                AppBar.Visibility = Visibility.Collapsed;
            }
        }
    }

.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; }

Remember, I am not advocating doing it this way, Visual State Groups remove a lot of this code in favor of something simpler.  The point here is to see how the developer is responsible for handling this.

Tips for Creating Snappable Pages

So one of the things that I learned in going through the Codemash Windows 8 app was generally you want to start with the “snapped” view. I feel the reason for this is the snapped view isnt going to be fancy or take advantage of the screen size.  The purpose of the “snapped” view is to provide the absolute minimum what the user would need, kind of data intensive view.  So if you are using a GridView to display nice tiles and support the horizontal swipe, maybe in snap you use the ListView for a vertical swipe scroll.  That is a pretty common use case.
Keep in mind that some pages will not be snappable, or shouldnt be rather.  An example of this in the Codemash app is the Session Detail.  There is just too much information on this screen to where it would be usable in the snapped state. To counter this, I looked at several apps from Microsoft (the Store app in particular) to see what they did.  They generally simple display the application icon on a solid color. This way the user knows the app is open, but that they have to expand the window to use it.
Finally, for the pages which are snappable, make sure you support back navigation and disable any app bars, if it makes sense.  For example, you have three buttons in the app bar, it might make sense to display them horizontally in the snapped state, or you could make them go vertical when snapped.  The choice is yours.  There is a lot of freedom with what you can do when display type changes.

Conclusion

Supporting snapped pages in Windows 8 apps is not required but any well polished app is going to need to support these different view states.  Microsoft makes this easy and straightforward, and with a little bit of abstraction can be made easy and consistent within your applications.  Furthermore, the snapped state requires you, the developer, to give even deeper thought as to how the user will interact with your application. I view this as a great challenge and a chance to really expand the experience for the user.

Review: Microsoft Surface

It really is amazing how things come full circle.  I still remember seeing Bill Gates on stage introducing the Tablet PC back in the early 2000s.  I remember being excited then and buying so I could use it for note taking during my study abroad in Japan.  I remember how it just didnt work all that well and eventually fell out of favor with the consumer and remained largely unadopted by businesses.

Fast forward to 2010 and the release of Apple’s immensely successful iPad.  Building on the touch technology pioneered in iPod and perfected in iPhone.  This device, in addition to the already successful iPhone, brought Apple heaps of mindshare and effectively removed Microsoft from any conversation about mobile form factors (even with Windows Phone 7).

But I knew this would come, anyone who knows Microsoft’s history knows they do their best work when their backs are against the wall.  And they delivered, on Friday, Microsoft Surface, a device which is their first foray into the tablet market and a sign that companies may have to rethink how they distribute products in the future.  The reliance on OEMs to handle the hardware side of it (Dell, HP, etc) may be coming to an end due to the needs of the experience to be top notch.  With that in mind, lets review Surface:

The Good

Lets start with the good, this is an amazing device.  In just under 10m I had the device out of the box, booted, setup, connected, and fully stocked with apps. The finish is very clean and Windows 8 functions on a tablet as beautifully as you would expect.  It really is designed for a tablet, though I am also enjoying it on my developer laptop.  Soon it will be going on my desktop machine.

I personally love the magnetic connector that the Surface comes with, Mac has had it for years (Microsoft actually owns this patent, which I found amusing) but it seems most OEMs disregard this feature perhaps in favor of saving on cost.  But Microsoft made the decision to include because Surface is designed to be, like the iPad, a luxury device.

I have always been a big fan of the design formally known as “Metro” its clean and expressive, yet simple at the same time.  Microsoft choose to take a different approach from Apple and offer a lower resolution screen and high contrast to make the screen seem brighter than it is.  This wont get you to retina, but Metro doesn’t need retina to look good.

Probably the most unique thing about Windows 8, and I believe this will be something both Google and Apple will have to address is “snapping”.  The ability to actually have two applications visible on the screen at the same time is HUGE.  Granted for developers it adds more complexity, but Microsoft has taken steps to make it easier, that will be in a future blog post.

I also love the unification of all application features: search, share, and settings into a single place.  Once you get used to this, it feels very natural and sensible.  Why should every application support search in a different way?

One of the other noticeable differences from Apple and Google is the integration with social media networks like Facebook, Twitter, LinkedIn, etc as well as contact and calendar integration across a variety of services.  This is something that Microsoft started doing in Windows Phone and they have evolved it hear beyond anything Apple and Google offer.  Microsoft has always stated that the device isn’t about just getting apps, its about representing your life and connecting you to the people in it, for that reason ANY app can share information to the various social networks you are connected to.

Productivity

As good as Apple’s office tools are, they still pale in comparison (and usage) to the Microsoft Office tool suite. This is a huge part of Microsoft’s business and the central reason why Office 2013 Preview (with the ability to upgrade to the full version when released) is included, for free, on all Surface products.  These are NOT Metro style apps; Microsoft is working towards making them so, but remember that Metro apps emphasize simple design, and the various Office applications often include a bevy of additional features, some of which dont make sense in the tablet experience.

At long last, Skydrive is finally taking center stage.  I have been using Skydrive, I swear, for about 7yrs, long before Dropbox or iCloud were even thought of, but Microsoft being Microsoft they never took advantage of this until Apple started featuring it in commercials for photo sharing.  In fact, ALL office products, by default, save to Skydrive if available (Internet required).

One of the other huge draws was the TouchCover.  I have handled an iPad many times and I hate the soft keyboard.  I hate working on a device that I should be able to type naturally but it feels anything but.  I hate giving almost half my screen real estate so I can have a keyboard.  On a 7” tablet this is alright cause I can still use my thumbs in portrait mode, but it does not work for a 10” (unless you have really big hands).  Microsoft understands, and wants, the office crowd to be one of the major buyers, so the TouchCover (or TypeCover) gives you an actual keyboard you can use, and you know what, it really works insanely well.  I watched several videos on how they made this thing and it is an impressive feat in engineering.  I am still getting used to it, mainly because while I do use two  hands, my style is a bit, weird, so its requiring some adjustment, especially when I move to hit the ‘a’ key.  But I am getting there.

The Bad

So its not all fun and games, Windows 8 is a big time change for most Windows users as it moves them into an era where touch is more dominant then point-and-click, which has been the Windows staple for almost 30yrs.  This OS is different, whether its different good or bad is for the individual user to decide.  The device does display a quick tutorial at the start illustrating the charms bar, but users have a bad habit of not paying attention to this.

One of my other concerns, though there is a way to indicate their presence, is that app bars.  On WP7 there was a small ellipsis exposed to indicate the presence of the Application Bar, that is gone (or made optional) in Win8, and I haven’t seen a lot of apps exposing it either.  The idea is to swipe down from the top or up from the bottom to expose extra screen features (context sensitive).  I don’t quite understand why we have TWO app bars, but I wonder how and when users will know when they are there. Most likely, once they do it a few times, they will know to try the swipe to see if anything else is there, but I believe this is not intuitive enough and will cause confusion.

While the People hub is nice it hardly can fully replace a standalone Twitter or Facebook client.  Just this morning my brother responded to a comment I made on Facebook and it took me a bit to find out where I could find this.  As there is not yet a Win8 Facebook client, People hub is the only option. So if you are really busy on social networks, the experience here could use some work or, better yet, be supplemented by specific apps.

Perhaps the most annoying this on Win8, and I cant tell if this is the software or the hardware, is the touch and drag of the tiles in your start menu.  I love having my new Start menu arranged in a certain way so that I group related tiles together.  Trying to move tiles around on Surface is PAINFUL.  You have to touch and hold and when the tile tilts move it down or up a little so the OS knows you arent swiping.  You can then move it around pretty freely and there are good markers to let you know how your drop will affect the UI.  But Microsoft needs to make it easier for people to move tiles, the current way is painful.

Conclusion

I have said this many times and I will say it again: “Give Microsoft credit.  Instead of going to the Google approach and using iOS as a template for how they approach UI, they went their own way and have actually innovated something”.  I have heard it a lot from Apple fans that I know that they really like to look and feel of Surface, some have already converted from iPad.  But lets not get carried away, and Sinofsky said it too, “this isnt a device for people who ‘love’ their iPad”.  Windows 8 is not perfect but I think its more evolve in many ways, specifically user interaction, than Apple or Google’s products.  The ability to have two applications open on the screen at the same time is a big plus and not something either competitors consumers enjoy at the moment, despite being all being used to the “windowing” idiom that most desktop/laptop OSes employ.

It really is nice to see Microsoft showing that they can still create great hardware (360, Kinect, etc) and deliver on the experience.  Based on a number of factors you can really see Microsoft is changing the way they think about products and how they deliver them, along with many other vendors spurred by the Apple approach.  The general consensus among the various tech outlets is this is a dramatic win for Microsoft and puts their name back into the conversation with Apple and Microsoft.

That said, I want to take a moment and an dditional things: Many of the reviews have noted the low App Count as being a diminishing factor in this product. While the app count is certainly dramatically lower than iOS, Android, and even WP7, the OS has only been available for a little over a month and was publicly launched Friday, October 26.  Does anyone want to take a guess at how many apps iOS had in 08 when the App Store opened?  There is not a magic app fairy that can suddenly create 50,000+ apps overnight, sorry. Microsoft has the tools that developers love so I expect the app store to begin filling quickly, but it will still take years before it reaches the levels of iOS and Android.

What Surface is, and Sinofsky said this too, its a different “perspective”.  This isnt like the iPad at all, its different.  Some will enjoy that difference, others will curse and hate it (I happen to love it).  But at the end of the day there is no denying that Surface is a quality product and 8 was made for tablets.  Welcome to the age of touch Windows users.

SQLite and Windows 8

One of the goals with my new Codemash App is reduce subsequent load time to almost nothing.  This means that aside from the first run, loading should be a near instantaneous act.  Obviously you cannot get away form some load time, but I wanted it to comparable to the act of grabbing your conference guide and flipping through pages.

Unfortunately, in the present release of Windows 8, not local database is supported for Metro apps.  I was disappointed by this, I figured SQL CE at least would be supported.  Whether this will change in the future I do not know.  With this in mind I went looking for an answer and found this post on Stack Overflow.  The guys at SQLite were kind enough to take it upon themselves to provide support for WinRT.

Installation

I used Tim Heuer’s blog post to understand things.  His video is somewhat dated however, as the SQLite team has in fact released something which can be included in Visual Studio to support SQLite.  This extension can be downloaded here.  Important to understand this is a visx file, meaning it will include the DLL on its own, you just need to list as a dependent extension.  See below:

After installation:
Tools –> Extensions and Updates…
image

All this means is you CAN reference it, not that it is referenced.  To actually reference it, do the typical Add Reference.  Looks under Windows –> Extensions.
image

Make sure you check the SQLite AND C++.  FYI, I know that most people use Any CPU as their compilation mode.  For a component like this, you’ll have to pick one, though it might support both.  I dont have an ARM device to test on.

At this point the SQLite libraries are a part of your project output, but you really dont want to be interfacing natively with the C++ library.  Thankfully, there is a nice LINQ based wrapper you can get from NuGet.

Install-Package sqlite-net (alternatively, you can do a search for it through the Manage Nuget Packages –> Online interface)

Run that command pointing at the correct project.  Once installed, our next steps to actually talk to SQLite will be easy.

Creating a Database

So SQLite is filed based, meaning its not your typical RDBMS system you are familiar with if you are coming from MySQL or SQL Server.  Its designed to be extremely lightweight, which makes it perfect for WinRT.  The concept of a “table” is not the same as what you would expect from the afore mentioned DB products.  Keep this in mind.

Lets “connect”

So, its not really connecting, you are opening a file.  So we have to dictate where we want the file stored.  Tim Heuer recommends storing it in the local ApplicationData folder, so that is what I am doing as well:

string applicationPath = Windows.Storage.ApplicationData.Current.LocalFolder.Path;
_databasePath = Path.Combine(applicationPath, DATABASE_NAME);

.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; }

We use this path whenever we establish the connection, like this:

using (var db = new SQLiteConnection(_databasePath))
{
       var entities = db.Table().ToList();
 }

.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 code opens the connection and does a select all against the Session “table”.  Remember, its not really a table as we understand it from RDBMS world.

Talkin’ bout saving data

Once you have established the connection, there are a variety of methods to support the CRUD operations.  One tip: define your PrimaryKey (look in the SQLite.cs file created) as shown below:

public class Session : EntityBase
{
    [PrimaryKey]
    public int SessionId { get; internal set; }

    public string Title { get; internal set; }
    public string Abstract { get; internal set; }
    public DateTime Starts { get; internal set; }
    public DateTime Ends { get; internal set; }
    public string Level { get; internal set; }
    public string Room { get; internal set; }
    public int SpeakerId { get; internal set; }
    public string Track { get; internal set; }
}

.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 would question anyone who has a complicated model being stored locally.  Traditionally, you want to keep these structures simple so they are easier to sync.  The idea of storing a complex database on the local system seems counterintuitive to me.  SQLite is not designed to support such an approach.  The amount of data being kept here is minimal and the operations simple, intentionally.

Closing Thoughts

I had worried that creating this feature would present various challenges, however I was wrong.  Thanks to Tim Heuer’s tutorial I was able to quickly get this up and running.  Quite honestly the tricky part was getting the code just right using the new async and await features so that I could do something of a thread join (though we aren’t using threads).  Once I got this to work just right the application worked as I expected, though I am still using DevLink data.  I hope to be using Codemash data starting sometime next week.

“But I’m not a designer” is not acceptable

As part of building a Windows 8 app for Codemash I have gotten the change to dive into the new layout controls featured in Windows 8, namely the GridView.  It has been an extremely challenging experience, but not due to technical difficulty, but rather the new thought process involved in creating an application.

I would say many of Microsoft’s developers are only now beginning to understand just how important design is, but they may not yet totally realize that design is fast becoming a developers task.  Gone are the days where saying “I am a developer, I don’t design”, developers of the future will be expected to design applications and consider usability as part of that process, more so than in the past.  Those of us engaged in mobile development are already doing this.  This is not to say that Graphic/Web designers are irrelevant in the future, quite the contrary, there will always be a need for professionals who specialize in design.  However, more often than not when developing an application a developer will find themselves without this support but still with the expectation to create something usable.  Remember, while the best solutions come from designers and developers working together, ultimately functionality outweighs look.  Developers are still needed more than designers.

What this means is, it still more important that the application be able to carry out a task than looking good.  However, the usability of the application is an extremely close second, especially with respect to mobile form factors.  The ability for you, as a developer, to not only code the application but also identify how the app will be used are essential skills for the future, especially as mobile form factors becoming the primary target platform.  Professional design skills will always be the domain of the expert, but cross pollination of design skills benefit both sides.  Few projects actually require professional design expertise to achieve a highly usable state.

Before everyone starts getting worried and running out to buy design books there is good news.  Microsoft, and other companies, have already realized this and have been infusing controls with good design features, leaving developers to make minor tweaks and pick colors.  Windows 8 is a great example of this.  Microsoft has already done the research and decided on a particular approach developers can work in to create high usability in their apps, Apple has a similar approach whereby XCode enforces the rules of the HIG (Human Interface Guidelines).

Designing the Codemash App

The biggest learning experience of the Codemash app came from understanding what I feel is important to the user.  This understanding is born of many conference apps and attending conferences in general.  What questions do I often hear people asking?  I want to make sure that information is readily available, otherwise the provided booklet is more valuable that any app.  I have to remember, I am creating an app to replace a book so I have to provide an experience that can be seen as greater in value than the book.

I felt that the most important thing for the conference attendee was what sessions were “upcoming”.  Thus I choose this to be the first screen the users sees.  A full session listing can be accessed through additional screens.

To achieve this I used the GridView which allowed me to create a tiled look with the Session Title, the Speaker Name, the Room and the Track.  The idea here is quick glancability at the general topic of the session (title and track), who the speaker is and where I can find it.  Of course the user can tap the box and be taken to the full details.

CodemashMain

I allow for three lines of text for the title, if it goes beyond that, it is cut off.  This is not the final design, I want to get some additional feedback on the text size and letter spacing, see if I can clean this up.

You can see that the two most prominent text blocks are the Track and Title.  This is intentional because it is designed to attract the eye and make a decision.  The conclusion I came to is the Speaker is simply not normally a deciding factor in choosing a session for most people.  For this reason, its size is smaller than Track and Title.  Smaller still is the Room, since this is certainly not a deciding factor, but information that is needed after a decision has been made.

I should point out that the data I am using, for the most part, is from DevLink 2012.  This was in an attempt to use something that could closely the mimic the data Codemash will provide once the REST API is updated with the new sessions.

Next Step

While all of the pages in the application are done, I don’t plan to show everything, I want some of this to be a surprise, as I anticipate many people will have Surface for CodeMash, I know I will.  That is the big question mark at the moment, how does this look on a mobile form factor.  I can run this all day on my laptop but I need a mobile Windows 8 form factor to really get a sense of the usability.

Back to the Design

Let me make clear one point, when I refer to the process of coding, I am not referring to HTML/CSS.  As a developer if you are NOT familiar with this, I would seek a new profession.  Given the importance of the Web, I am left aghast at any developer I find with no knowledge of how to develop for the web.  The best designers are also those who are good with HTML. Understanding how a design will be implemented is a key skill as it helps you understand what works and what does not.  This is no different than a programmer who pushes back on a feature that the current code base will not support.  The more we understand our target the better we can achieve it.

It will never be necessary for designers to replace developers, nor will it ever be necessary for developers to replace designers.  But as developers who can already understand the back end code behind how something works, have the ability to contribute to how it looks and is interacted with is an essential.  Cross pollination between these two realms should be encouraged.

The Conference Delta API

So I haven’t been blogging a lot, mainly because I have been busy, both at work and on the side.  During DevLink I had an idea come to me for a new project, which would test me in many of the new technologies that Microsoft is developing, specifically: Azure, WebAPI, and Windows 8.

In recent years, many conferences have begun exposing a REST API listing their session and speaker information.  Conference-goers have been encouraged, and have done so with remarkable results, to create smart phone apps to negate the need for attendees to use paper to find sessions.  While these apps have been largely impressive, they tended to suffer from one major flaw: load.  Whenever someone opens their app they generally have to download all of the latest data to ensure that any changes (as happen frequently at conferences) are taken into account.  With so many developers accessing the API load times can be extended, so much so that people tend to fall back on using the physical medium.

The project is designed to address this shortcoming as well as provide me a chance to dabble with Microsoft new Windows 8 platform.

The Poller

To address the load issue it is necessary to provide an API which can, along with providing the latest conference information, provide changesets which detail, simply, what data has changed.  These would be smaller packets.  To facilitate building these changesets, I created a Azure Worker Role which is designed to poll an API every so often and determine what has changed, if anything.  This data is then stored in a SQL Azure table.  The next step was to provide a way for users to access these changesets, along with the latest information for the conference.

The Delta API

So, in what I call a Proxy Pattern (I am sure it has a more formal name), I am creating a web instance to sit in front of another instance.  For the current implementation 4 things will be provided by this proxy API: Speaker information, Speaker Change information, Session information, and Session Change information.  This is a simple WebAPI which can return the data in JSON or XML format, depending on what the consumers asks for.

The Push Service

So one of the central features in Windows 8 and Windows Phone 7 is the MPNS (Microsoft Push Notification Service).  By utilizing this proxy approach I can allow for Push notifications about conferences changes to be pushed to subscribers.  I am also thinking, I can notify when a session is about to start, as a reminder.  I am hopeful that should my pilot of this system prove successful I can extend the push notifications to Apple and Google (via UrbanAirship, most likely).

The Clients

Because the DeltaAPI provides the data in JSON and XML formats, I could write a client for ANY platform, but as I carry a Windows Phone and I will be buying a Surface, I am targeting the Windows platform.  I am looking for other developers who would be interested in developing for Apple or Android platforms.  At the moment, I am working on the Windows 8 client application having finished the Delta API, Poller and Azure deployments.  I expect the Windows 8 client to be completed by end of week.  I am trying to do this ahead of a critical date for this project with respect to the pilot.

The Pilot

At the moment, I am awaiting the release of the CodeMash session selections (I may be one of them).  Once the API is released I intend to target it and begin building the data.  It will require some code changes as DevLink (which I used as a model) provides different information than CodeMash.  I am looking for anyone interested in developing apps for Apple and Android as I will simply not have time to address these platforms.

So there it is, its ambitious and part of a much larger goal I have for distributing conference data.  I am hoping for a solid pilot at Codemash this year.

DevLink 2012 Windows Phone 7 App

It was most unfortunate that due to time considerations with the Windows Marketplace Approval process, I was not able to deliver the working app to WP7 users outside of a side loading option.  That said, I thought I would take some time now and talk about the app and my thoughts with respect to quickly developing a Windows Phone 7 app relative to what I know about developing for the other platforms.

Code: https://github.com/xximjasonxx/Devlink2012

Why

It was amazing to me that with DevLink being a fairly Microsoft-centric conference that when I checked the Wednesday before the conference there was no app for WP7.  I feel this is a blow against Microsoft, though perhaps a sign that developers are turning their attention to Windows Phone 8.  But regardless, with no app in the market I elected to develop one for two reasons: 1) I needed the app for myself and 2) I wanted to see how fast a fairly advanced Windows Phone app could be develop and compare that against what I have experienced developing for iPhone and Android.

Design

I had less than a week to build the app so the design would need to be simple.  I decided to utilize the MVVM pattern with Caliburn.Micro supported by Dependency Injection using Ninject.  The bsaic idea was a repository based approach which would load all session data at the application launch and then allow the user to see the data in different viewings to get a better idea of what was available.

From a look and feel perspective, I wanted the initial page with two sections on the panorama: 1) my sessions where users could see the sessions they had starred and 2) upcoming sessions which would allow the user to see sessions for the next three blocks.  The second feature was from feedback from the app I developed for Codemash 2012 on Android.  Since I would be displaying the session information relative to its block I would need some way to display hierarchal data.  I initially considered a templated ListBox but then I saw the ExpandView from the WP7 toolkit.  This is the same control used in many of the email controls on Windows Phone 7.  After some work, I was able to repurpose it for my needs

Implementation

As I said, I intended to use the repository pattern and would be focusing only on the session data, this due to my limited time constraints.  I used RestSharp to make communicating with the DevLink REST service feeds easier and then used the Newtonsoft JSON library to aid in the conversion of the JSON to my POCOs.  To use the repository pattern within Windows Phone 7’s inherently async programming model I used an event paradigm where each call into the repository would result in an event being raised when the operation was complete, much like what RIA Services does.  This proved to work very well and combined with a strategy to hold data in the repository for 10m my subsequent calls were quick and painless.

The implementation called for two repositories: ISessionRepository and IFavoriteSessionRepository.  The latter would be responsible for tracking what session the user had favorited.  This data would be merged with the session list to populated the “my sessions” portion of the application.

CM provided automatic wireup of the ViewModels which allowed me to separate these operations from the view very simply.  The trickiest part was getting my sessions and upcoming sessions to respect each others changes.  Due to the delay in how the Property Change notification works, sometimes this resulted in a clunky UI.

In addition to these two sections and a corresponding Session Detail page, which listed all available information for the session, I created another page using the Pivot data control which would allow the user to view the session data with different groupings: block, track, room, etc.

Failure

During my initial testing everything worked well and so I elected to submit my application for approval on Sunday, August 26, 2012.  However, upon arriving at the conference and using the app myself I noticed that more often than not the app would crash when going to the Pivot portion.  I hypothesized that it was simply trying to do too much.  So despite the app being initially approved on August 28, 2012 I elected to forgo its approval and try to work out a solution.  I eventually did: I broke the page apart and gave the user a page to select what they wanted to see.  It worked well and the app was resubmitted.  However it would not be approved before the end of the conference.

The conference organizers, one of whom was a Windows Phone 7 users, still helped promote the XAP I deployed to my Skydrive, but in the end, it seems, I was the only one who ended up using it.  But this experience and conversations about the other options gave me some ideas for Codemash.

Final Thoughts

All in all I was able to develop the app in just under 21 hours and have it be fairly feature rich.  The biggest problem was the noticeable delay when notifying the View that a property changed.  There doesn’t seem to be a way with CM to know when this is complete.  This often resulted in the screen being blank despite the fact that everything was alright.

Outside of seasoned Android and iPhone developers I really think this shows that even for a newbie like myself Windows Phone brings the performance and efficiency developers expect to a mobile platform.  I like both iPhone and Android, but Microsoft truly is the developers company and has the best tools.  Visual Studio and the various language features of C# made developing this application a breeze.  In the end, what did me in was not leaving enough time for the approval process.  Developing it gave me some ideas for Codemash, in particular, finding a way where a person could have the latest session information without downloading all session data.

To conclude, I think the experiment was a success because I was able to develop the app in such a short amount of time.  Microsoft’s tooling for developers is truly second to none, now if they could just sell some damn phones I might be able to use WP in conversations involving Android and iPhone.

Code: https://github.com/xximjasonxx/Devlink2012

The synchronized Ajax call with Deferreds

As I mentioned previously, one of the most exciting sessions at DevLink was Asynchronous JavaScript.  My biggest spark was from seeing an answer to a problem I have faced down many times and the solutions I have come up with always made me die a little bit inside.  I hated chaining JS callbacks for the specific purpose of making a secondary Ajax call, especially when the data was unrelated.  The answer to this is something that has existing in JQuery for a while now, I actually had heard of it but had not realized the full scope of what it brought to the table.

The idea of a Deferreds is to create a single object which can notify all other callers.  This allows you to define handling logic that is executed only after both calls have completed successfully.  I decided to craft a very simplistic example of this, just a couple calls to the Twitter Search API, here is the function that does the Ajax call:

function makeTwitterSearchRequest(query) {                             
    return $.ajax("http://search.twitter.com/search.json?q=" + query, {
        async: true,                                                   
        contentType: 'application/json',                               
        dataType: 'jsonp',                                             
        data: {},                                                      
        type: 'GET',                                                   
        crossDomain: true                                              
    });                                                                
}                                                                      

.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; }

(to make this fit I did omit certain parameters from the Twitter Search Request)
Notice that this code returns the call to $.ajax.  This is important.  Since JQuery 1.5 the success, error, and complete handlers are being phased out in favor of this new model.  You see what this method now return is a “promise” which is a wrapped version of the Deferred ($.Deferred).  The reason a promise is called is for the sake of proper encapsulation, wont get into that here.  Just understand that the fact it returns a “promise” is why the new pattern is to use the done(), fail(), complete() methods to handle the various outcomes.  But this gives us another benefit, we can use the results in conjunction with other methods in the Deferred architecture, like this:

var appleRequest = makeTwitterSearchRequest("apple");                   
var microsoftRequest = makeTwitterSearchRequest("microsoft");           
                                                                        
$.when(appleRequest, microsoftRequest).then(function(apple, microsoft) {
    var appleResults = apple[0].results;                                
    var microsoftResults = microsoft[0].results;                        
}).fail(function() {                                                    
    alert("failure");                                                   
});                                                                     

.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 the power of this approach and what has me so excited.  I make TWO AJAX requests and the handler is NOT called until they both complete.  And the handler gives me access to all of the information I would need within the menu.  This is effectively synchronizing threads (though JavaScript does not have threads per-se, just one giant ass event loop).

I cannot understate how cool and efficient this is.  While JS is not multi-threaded and thus cannot get the ultimate benefit from this approach, it does allow the code to be cleaner, which for the programmer should always be a vitally important goal.  I cannot tell you how many times I have run into this scenario where I would love something like this.  Cannot wait to use it in production, and to think it was there all this time.