Customize Your Mobile Service Endpoints

In my previous post I spoke about how Mobile Services is good at giving you a REST endpoint where you can store data.  This time I want to show off what you can do with node.js as data is read/inserted through these endpoints.  These are very common operations that we often handle as part of our REST calls.  It further illustrates how node.js JavaScript comes to serve as your server side logic code.

Reading

Normally when you make a request to a Mobile Services table (or endpoint) request.execute() is called causing an array of JSON objects to be returned comprising the contents of the table (or subset if a filter is provided).  While this is the general use of READ, what about a cause where you want to augment to return with some additional data.

As part of the demo for my Mobile Services talk, I want to pass the READ the token of the device and return back a listing of the stored channels with a boolean field indicating whether the device is registered with that channel.  To do this, I will have to talk to an additional table to determine whether the device is registered.

I will point out that due to some of the decisions made by Mobile Services this process is not as clear cut as you would expect it to be, especially if you commonly work with .NET.  For one thing, any database operation has a callback, operations are not synchronous (despite being on the server).  With that in mind, our first goal is to read out the stored channels from our Channels table:

    var channelTable = tables.getTable("Channels");
    channelTable.read({
        success: function(results) {
            var returnResult = [];
            results.forEach(function(result) {
                var channelName = result.Name;
                var channelId = result.id;
                
                returnResult.push({
                    Id: channelId,
                    Name: channelName,
                    Registered: false
                });
            });
            
            returnWithRegistrationStatus(returnResult, token, request);
        }
    });

.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 get a reference to our table (Channels) and then simply call readread takes a single parameter which allows us to define options (the documentation does not seem to list what other options exist), one of these supported options is a success callback; you will find this pattern used throughout server side coding using MS, I am still undecided on whether I like it or not.  It is because of this pattern that I had to structure this relatively simple and straightforward operation is such an interesting way.  As I create my return result set, I default the IsRegistered to false.  But notice, the JSON object I am creating is not indicative of the schema for Channels, it is entirely custom and is what we will return once we update IsRegistered,

The second part of this is the returnWithRegistrationStatus method call.

function returnWithRegistrationStatus(results, token, request) {
    var assocTable = tables.getTable("ClientChannels");
    assocTable.where({
        Token: token
    }).read({
        success: function(regs) {
            regs.forEach(function(reg) {
                var channel = getChannel(reg.id, results);
                if (channel != null)
                    channel.Registered = true;
            });
            
            request.respond(200, results);
        }
    });
}

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

With this block, a read is performed following a where call on the ClientChannels table.  In the case of where, you simply pass a JSON object representing what data you are looking for.  We then analyze the results and update the IsRegistered flag as appropriate.  The final important aspect to this function is the request.respond(200, results) which effectively terminates the read call sending the 200 response code, with results serialized as JSON objects.  This is your response.Content on the other end.

I should also point out how I got the token value into the read call.  This is the C# code from the device which makes call to the read operation of the Channels endpoint.

var table = client.GetTable("channels?token=" + url.AsToken());
var result = await table.ReadAsync(string.Empty);

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

Notice, that I am using GetTable with a query string, it is read in the endpoint like this.  The string.Empty call is effectively an empty filter.  Since we arent actually using the filter directly in the read call, this really is irrelevant in this case.

var token = request.parameters.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; }

Simple.

Inserting

One of the other common operation is a multi tier insert.  In my case, when I attempt to associate a client with a channel, I want to check if that client is registered.  If it is not registered I want to insert it and then perform the association.  As with the read operation, this normally simple operation requires a bit of thinking to work with the callback structure of the calls we will use.

    var clientTable = tables.getTable("Clients");
    clientTable.where({
        Token: item.Token
    }).read({
        success: function (results) {
            if (results.length == 0) {
                console.log("creating the client");
                RegisterClient(item.Token, item.ClientType, item.ChannelId, request);
            }
            else {
                console.log("associating the client");
                RegisterWithChannel(item.Token, item.ChannelId, request);
            }
        }
    });

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

Here, depending on whether or not the given client (identified by the token principally) we will call a different function.  This is similar to the read in that it users a where call combined with read.  Registering a client is nothing more than inserting a record into the Clients table.  Here is the code for RegisterClient:

   1:  var clientTable = tables.getTable("Clients");
   2:      console.log("inserting client");
   3:      clientTable.insert({
   4:          Token: token,
   5:          ClientType: clientType
   6:      }, {
   7:          success: function(result) {
   8:              console.log("associating the client");
   9:              RegisterWithChannel(token, channelId, request);
  10:          }
  11:      });

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

Pretty straightforward, as with most operation, simply pass a JSON object to the operation as allow Mobile Services to figure things out.  In this case, in addition to the standard id column, Azure Mobile Services will create two additional columns: Token, ClientType.  Upon the successful completion of this operation, the script moves to perform the channel to device association.  Here is the code for RegisterWithChannel:

function RegisterWithChannel(token, channelId, request) {
    var assocTable = tables.getTable("ClientChannels");
    console.log("adding association");
    assocTable.insert({
        Token: token,
        ChannelId: channelId
    });
    
    request.respond(200);
}

.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 similar to the RegisterClient method. It inserts a token and channel Id into the ClientChannels table.  Interestingly, it seems that if you perform this operation from within the trigger, the trigger does not get repetitively called.  I was worried about this, because we are effectively inserting into the table whose Insert script is being executed.  The fact that this repetition does not occur further proves that the purpose of scripts is to perform server side logic and act as a front for the incoming data.

The final operation is the call to respond on request which terminates the script.  In this case, I am not returning anything to the calling code, although it is conceivable that you could return a JSON object as the second parameter with additional information.

Closing Thoughts

It is clear that Mobile Services is a work in progress.  While the editor for these scripts is very nice and I applaud Microsoft for providing a good developer experience it is still lacking.  Right now, the best means of debugging are going to be calls to console.log.  I have no doubt this will improve, but for the moment it can make development tricky.  Also, the documentation (http://msdn.microsoft.com/en-us/library/windowsazure/jj554226.aspx) could use some elaboration and additional examples.

By far the most annoying this is the structure of these scripts.  Operations that should be straightforward and simple require much thought to adhere to the callback pattern.  I would prefer to simple call .read() and work with the results that way as opposed to relying on callbacks which can make code messy very quickly.  This in conjunction with the reliance on console.log make developing complex scripts difficult.

Your Mobile Service as a REST Endpoint

One of the things I like about Azure Mobile Services is how the integration with node.js gives you the ability to quickly generate a compliant REST API along with quickly standing up backend persistence.  Using node.js and the operational triggers attached to each created table, you can very easily perform all sort of data operations and produce common REST like behavior.

A Bit About REST

This is something of a soapbox for me.  REST is not strictly related to web services, it is designed to be much closer to the metal than that.  If we think about web service technologies such as SOAP, we see something that is built on top of HTTP, adding additional overhead to provide additional functionality.  This is different from REST.  REST is about using what HTTP gives us rather than supporting an RPC style web service.  Instead of thinking about calls to the API as functional calls, REST has us think of them as if the user were simply browsing; thus we can rely purely on HTTP for all matter of things.

Take for example, errors.  Very commonly I see developers returning “error” objects from REST; this is, in my opinion, not correct.  HTTP already has errors and error codes, in fact you run into them every day, ala the infamous 404 error.  In a pure REST implementation, if you user was not found you would return a 404 from the server, not an error object.  Your client code would then interpret it.  If the user attempts to access a resource to which they do not have access, the servers returns a 401 (Forbidden).  In short, REST is about using what HTTP gives you, rather than building on top of HTTP as is the case with something like SOAP.

Back to Mobile Services

Azure mobile services provides an endpoint for each table you create.  So if you create a table called “People” you have an endpoint: <a href="http://http://<mobile service name>.azure-mobile.net/tables/People.  Using this endpoint you can send a variety of verbs (POST, PUT, DELETE, GET).  Depending on which verb is used will indicate which node.js trigger is invoked as a precursor to the action operation.  Here is the mapping:

  • POST => Insert
  • PATCH => Update
  • DELETE => Delete
  • GET => Read

At minimal, the script must call request.execute() which indicates the operation should be processed.  You can add conditional logic, ie validation, and use request.respond, which will allow you to pass back an HTTP status code along with a message.  In the case of invalid data, you would not call request.execute().

I admit, I find it rather strange to use the PATCH verb over put to invoke UPDATE, it definitely tripped me up when I first started playing with updates.  However, according to the Azure team, because the default functionality does property –> column matching, it in conceivable that a subset of properties could be sent thus “patching” the existing object, as opposed to a full scale update which is what the PUT verb is commonly associated with.

But how does it know?

So you may be thinking, how does DELETE and UPDATE know what to update.  The answer is, the id column.  Each table in Azure Mobile services is REQUIRED to have an id column, in fact it is automatically created when the table is created.  These operations will automatically key off this id.  Here is an example of the URL to the endpoint:

https://pn.azure-mobile.net/tables/Notifications/1

This will update the record in the Notifications table with the id of 1.  You would pass a JSON object in the request body with the values to replace with.

So what is the result?

The reality is REST is designed to work with resources, its not really designed for endpoints per se.  It is designed so you can query a resource in different ways and perform actions based on those verbs.  With that in mind, I really find what Microsoft is doing with Mobile Services very cool.  Not only do they provide a backend that is easy to work with, they are also allowing developers to quickly implement REST API on those tables/resources using node.js.

For reference: http://msdn.microsoft.com/en-us/library/windowsazure/jj710108.aspx

SignalR and Azure Websites Error

SignalR and Azure Websites Weird Error

Working with some finishing touches making my Push Demos more consistent I started encounter a failure with SignalR when I deployed to my Azure Website.  I had to deploy the JS code with a debugger; statement and then use Chrome to get the actual error:

“The data protection operation was unsuccessful”

I am still working to understand what this actually means but in the meantime Stack Overflow was once again useful in finding a way around this problem: http://stackoverflow.com/questions/15393684/signalr-cryptographicexception-on-azurewebsites

It seems to be related to the Cryptography settings on Azure Websites, I hope to provide more useful information later.  For now, I hope to save people anguish by at least offering a solution.

Update

After conversations with David Fowler and Damian Edwards (the creators of SignalR) I have discovered the above implementation is extremely insecure and not recommended.  The problem is actually the usage of a custom Dependency Resolver for SignalR.  Because mine is custom, to allow dependency injection via Ninject, I was not getting the provided IProtectedData dependency.  The answer, for Ninject is the following block:

_container.Bind().To();

This will correctly fix the problem and maintain security.  Cheers

Windows 8 Access Forbidden

I was doing some development last night on some demo apps and I ran into this lovely error message:

“An attempt was made to access a socket in a way forbidden by its access permissions 192.168.1.18:80”

I got this exception when I attempted to access a Web API service I wrote from my Surface while doing some Remote Debugging.  I kept getting errors indicating the connection could not be resolved.

I did some digging and came up with the exception above, and it seems the solution isn’t overly obvious.  You have to check the following box:

image

This only seems to apply when you are talking to a server internally.  But it might apply elsewhere.  Real annoying, hopefully this posts save some people some time.

Push Notifications with Azure

Recently I have been working on a new talk for speaking engagements.  The topic is Push Notifications which is something which come to the forefront more and more for app development.  As this happens the various OS players have continued to enhance the Push experience within their platform.  The talk was aimed at explaining Push Notifications, their importance, and how to support them in a cross platform way.

Having used Parse in the past I immediately defaulted to using it for the Android and iOS side of my talk, it seemed logical. I was midway through my presentation when I attended a talk at Chicago .NET Developer Group which focused on using Azure as a backend storage for Windows 8 apps.  Now, I had heard about Mobile Services and knew that Microsoft had been working to develop this service.  But I had heard it was limited to only Apple outside of the Microsoft stack and that it was still a work in progress; the talk, done by Adam Hoffman, showed me how wrong I was.

I know from experience that doing push notifications, even on Windows Phone, is not easy and requires a lot of knowledge about XML and the networking stack; so imagine my shock when I realized that Mobile Services could not only handle this for me for my Windows apps but also my iPhone and Android apps.  That with a single line of JavaScript run through node.js on Azure Mobile Services I could easily send notifications to any platform I desired.  And finally, imagine my glee when I saw the setup and just how remarkably easy it was.  Needless to say, my jaw about hit the floor and I promised Adam to check out Mobile Services over the weekend to see if I could fit it into my talk.

Forget fitting it in, I dont think I will ever use Parse again.  Over the course of one weekend I went from being behind in the development of my demo to being ahead of schedule.  I was able to completely overhaul my demo apps architecture and replace it with something that is very clean and consistent.  And, most importantly, I got consistent functionality from Android, iPhone, and Windows Phone apps.

Using the node.js + data table integration point, I was able to write a simple JavaScript script file which handles all of my push notifications for all of my clients, the details for those clients is stored elsewhere as the one shortcoming of the Mobile Services REST API vs Parse is the lack of an endpoint for sending a Push Notification via REST; I am sure the team will address this, in the meantime we have the Storage Table REST API which I was able to use in its stead.

The other nice thing is since Mobile Services uses SQL Azure as the storage mechanism you can access it with SQL Server Management Studio.  In this way you can view your data and interact with it in a much more robust way than with Parse (I cant speak to other services like Urban Airship or Pusher).

I do not want to give away the details of my talk on this post, that will  happen after its debut at Chicago Code Camp on April 27th, but I have to be honest.  What Microsoft is doing with Mobile Services is truly amazing; to think they even took the step of using GCM (Google Cloud Messaging) for Android Push Notifications when most Android devs either arent aware of it or dont use it shows an impressive amount of foresight.

If you havent checked out Mobile Services, do yourself a favor and do it.

Using Guice in your Android project

Some time ago I wrote the Pay It Square (http://www.payitsquare.com) Android application for a couple friends as a way to promote their service on the Android platform.  Prior to this while I had done Java programming in the past it was not of the “advanced” variety, at least not as high level as what I do in .NET.  This being the case it was my first true exposure to DI in Java.

For DI on Android we used RoboGuice (https://code.google.com/p/roboguice/) which allows for various forms of injection to assist the Android developer in developing the common boilerplate code (ie: getting a reference to a view in a related layout).

For my upcoming talk on Push Notifications talk I wanted to create the Android demonstration app using this tool.  Having been a while since my last big foray into Android I noticed that RoboGuice had recently been updated to version 2.0.  No problem, the instructions (https://code.google.com/p/roboguice/wiki/InstallationNonMaven) seemed clear enough.  However, I quickly found out that something was wrong.

After adding the files as Jar references and then as Library references I kept getting an error relating to the Provider and Class Not Found.  At first I thought I was not referencing the Jar files correctly in IntelliJ.  However, this was not the case.

After breaking things down to their simplest form, I found that a certain Jar file that I thought I had (courtesy of the RoboGuice download) was in fact not correct.  The answer to solving this was to download the files separately:

The problem child here is the javax inject library which supplies the ability for guice to “inject”.  The link above references a ZIP file which contains the javax.inject.jar file.  Add all three of these JAR files as Library references within IntelliJ and everything should work fine.  Leave comments if they dont.

Create a Sliding Window effect in iOS

As part of my learning iOS I have really started to dig into new aspects of the platform which are challenging me to better understand what iOS and Objective-C offers.  While it has been tough at times due to my familiarity with the Microsoft stack I feel that I am making progress.  One of the effects that is used heavily in Windows Phone applications is the idea of the user being able to slide (using the swipe gesture) from screen to screen; I wanted to duplicate that in iOS.

Approach 1: The ScrollView

Talking with some fellow iOS developers they recommended using a ScrollView and adding SubViews to that ScrollView to represent each of the screens.  I decided to use Storyboards as they appear to be the way forward recommended by Apple for developing UIs, and I really like the tool, it reminds me of what I wish Sketchflow had been.  However, I am finding that in many cases I am having to translate blog entries with use XIB files to Storyboard since most of that content was authored before Storyboards existed.

I found a great tutorial explaining this approach: http://www.iosdevnotes.com/2011/03/uiscrollview-paging/.  Just a word or warning if you intend to use this approach, watch out for ‘Auto Layout’.  It appears an issue exists, I can’t say for sure if its a bug or not, with storyboards.  This checkbox is checked by default when using Storyboards:

NewImage

When this box is checked the ScrollView will not come back with a size, even though it is set to fill the screen.  This is a problem since the code in the tutorial relies up on the size being there for mathematical calculations.  Deselect this checkbox and the code will work perfectly.

It might be my unfamiliarity with Objective-C/iOS but it appeared with this approach there was no way to load a view controller into the subview.  I didn’t want to A) support all of my screens from one view controller and B) I didn’t want to mix XIB and Storyboards.  Thus I began looking for an alternative approach.

Approach 2: The UIPageViewController

As it so happens, Apple has a template for this: Page Based Application

NewImage

At the center of this template is the Page View Controller (UIPageViewController).  This appears to be the Apple recommended way to create the effect we are going for.  Its actually quite simple.  I was able to deduce most of the process by analyzing the default code that comes with the template.

Given the application I am working on was already in progress, naturally I didn’t start with the Page Based Application as my starting template, so I had to add this functionality in.  Let’s walk through how I did this:

1) The very first thing I did was remove my existing “landing screen” and replace it with a Page View Controller.  I then made sure that my original MainViewController was changed to MainPageViewController and inherited from UIPageViewController.  This allowed me to select the controller from the drop down and directly associate the ViewController with the View (the Apple template does not do this, not sure why).

2) With this in place I added three View Controller views to the storyboard.  See, the Page View Controller acts as a container, these pages represent the actual content that will be shown within the container.  If you look at the default Apple template this is was what DataViewController represents, however, they are simply giving this controller different data depending on the month.  Since my application contains three discrete screens for view, with different functions, I need to create each screen individually.  Very important, we need to give each of these views an ID that we can refer to them with.  Specify it as the StoryboardId:

NewImage

You should also add some minor UI to each of your screens, this will help visualize if the effect is working or not.  Also, be sure that the Transition Style is set to scroll.  This will give you that nice transition so that it looks to the user like they are scroll:

NewImage

3) Before we get to the wire up, we need to create a controller of sorts to take care of the Data and Interaction portions for the PageView controller.  You can use your existing ViewController for this if you want, but I find that creating a separate class lends itself to better readability and keeps things from becoming congested in the MainPageViewController.  For this reason I created the PageController.  Here is the interface definition from the .h file

@interface PageController : NSObject <UIPageViewControllerDataSource, UIPageViewControllerDelegate>

You can see we are enforcing two protocols, which will dictate the methods available by this class.  However, I also added a couple of my own for ease of use

– (id) initWithViewController:(UIViewController *) controller;

– (OneListScreenViewControllerBase *) getStartingViewController;

These methods will be used by the code later on when we get to the wire up portion.  Lets walk through the methods in this class:

– (id) initWithViewController:(UIViewController *) controller {

    self = [super init];

    

    if (self) {

        // initialize the listing of view controller names

        pageViewControllerNames = [[NSMutableArray alloc] initWithCapacity:3];  // only three pages at present

        [pageViewControllerNames insertObject:@”ListActivity”atIndex:0];

        [pageViewControllerNames insertObject:@”MainListing”atIndex:1];

        [pageViewControllerNames insertObject:@”ListDetail”atIndex:2];

        

        // store a reference to the root view controller

        rootViewController = controller;

    }

    

    returnself;

}

This method is responsible for initializing the PageController (its the constructor for all intents and purposes).  Notice that we create an NSMutableArray with three strings.  These strings match the names you used for StoryboardId in Step 2.  They also represent the order, left to right, of the screens.  Finally, I am creating a reference back to whichever UIViewController is to be associated with this Page Controller.  Since all ViewController inherit from UIViewController it is the most abstract type I can use for this, this allows this to work with anything.  We will need this reference later on.

Note: Below there is a reference to a type ScreenViewControllerBase, this is a custom type I created which inherits from UIViewController and is the base class for all of my “pages” or the views that will be displayed in the container.  This was done so I could write the methods below to more general and not have to hard code which types to return at what indexes.  Here is the interface definition (.h) for this type.

#import

 

@interface ScreenViewControllerBase : UIViewController

 

@property (strong, retain) NSString *storyboardId;

@end

Now let’s discuss the methods in PageController

– (ScreenViewControllerBase *) getStartingViewController {

    return (ScreenViewControllerBase *)[selfviewControllerAtIndex:1

                                                               storyboard:rootViewController.storyboard];

}

Here we are indicating which view should be displayed when the user see’s first.  In this case I am starting at index 1, which is in the middle.  You can see the reference to rootViewController to get the storyboard.  This is the reason we used a custom override for init.

 

– (ScreenViewControllerBase *)viewControllerAtIndex:(NSUInteger)index storyboard:(UIStoryboard *)storyboard {

    return [storyboard instantiateViewControllerWithIdentifier:[pageViewControllerNames objectAtIndex:index]];

}

 

The rest of these methods are implemented as per the UIPageViewControllerDataSource and UIPageViewControllerDelegate protocols.

– (ScreenViewControllerBase *)viewControllerAtIndex:(NSUInteger)index storyboard:(UIStoryboard *)storyboard {

    return [storyboard instantiateViewControllerWithIdentifier:[pageViewControllerNames objectAtIndex:index]];

}

This method simply returns the ScreenViewControllerBase that is found at the given index.  It uses a reference to the storyboard to instantiate the view controller based on the StoryboardId.  This is why providing the StoryboardId is important, it allows us to leverage the View -> ViewController associations stored in the storyboard to return the appropriate view controller for a view. 

 

– (NSUInteger)indexOfViewController:(UIViewController *)viewController {

    ScreenViewControllerBase* oneListScreen = (ScreenViewControllerBase *) viewController;

    return [pageViewControllerNames indexOfObject:oneListScreen.storyboardId];

}

You may have noticed that ScreenViewControllerBase also exposed a property named storyboardId.  This was done to handle this method.  Here we are returning the integer position of the view controller (and the view) within our screen set.  This is used by paging to realize when we have reach the end of our listing.

 

– (ScreenViewControllerBase *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController

{

    NSUInteger index = [self indexOfViewController😦ScreenViewControllerBase *)viewController];

    if ((index == 0) || (index == NSNotFound)) {

        return nil;

    }

    

    index–;

    return [self viewControllerAtIndex:index storyboard:viewController.storyboard];

}

 

– (ScreenViewControllerBase *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController

{

    NSUInteger index = [self indexOfViewController😦ScreenViewControllerBase *)viewController];

    if (index == NSNotFound) {

        return nil;

    }

    

    index++;

    if (index == [pageViewControllerNames count]) {

        return nil;

    }

    return [self viewControllerAtIndex:index storyboard:viewController.storyboard];

}

These two methods work in conjunction with each other depending on the direction the user swipes.  One decrements the index and one increments it.  Both return nil to indicate the end of the road.  It would be possible, I presume, to simply add reset logic in these methods such that you can do a wraparound.

4) The next step is a bit boring.  We need to define a view controller (that inherits from ScreenViewControllerBase) for each view in our content.  In my case I added three:

#import “ListActivityViewController.h”

 

@implementation ListActivityViewController

 

– (void)viewDidLoad

{

    [super viewDidLoad];

    

    self.storyboardId = @”ListActivity”;

}

 

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

 

@end

 

#import “MainListViewController.h”

 

@implementation MainListViewController

 

– (void)viewDidLoad

{

    [superviewDidLoad];

    

    self.storyboardId = @”MainListing”;

}

 

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

}

 

@end

 

 

#import “ListDetailViewController.h”

 

@implementation ListDetailViewController

 

– (void)viewDidLoad

{

    [super viewDidLoad];

    

    self.storyboardId = @”ListDetail”;

}

 

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

}

 

@end

 

You notice that as of right now there isn’t much going on in any of these classes, but importantly look at the assignment of storyboardId and recall the purpose of this property from Step 3.  This is a textual identifier to aid in view controller look up.

After you have created these classes (remember they should ALL inherit from ScreenViewControllerBase) assign them to each of the normal View Controller visualizations on your storyboard

NewImage

We are now done with our setup, time to do the actual wire up.

5) Most of this is going to happen in our MainPageViewController, that is the controller which is acting as a container for the other views.  So lets look at the viewDidLoad method

– (void)viewDidLoad {

    [superviewDidLoad];

    

    // setup the paging system

    self.pageController = [[PageController alloc] initWithViewController:self];

    self.delegate = self.pageController;

    self.dataSource = self.pageController;

    

    // get the first view

    NSArray *viewControllers = @[[self.pageControllergetStartingViewController]];

    [self setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForwardanimated:NOcompletion:NULL];

    

    [self didMoveToParentViewController:self];

    self.view.gestureRecognizers = self.gestureRecognizers;

}

It really is nice when we properly inherit, if you looked at the default template from Apple and then at this, the simplification makes it night and day, I am simply not sure why the example doesn’t use inheritance like it should be used in this case.  In any event, only three sections here.  Since the view controller that we are in is a UIPageViewController we need only indicate the delegate and datasource for handling the paging operations.  We used our custom “constructor” initWithViewController passing an instance of ourselves to the instance of PageController.

Regrettably I have not found out how to do section two from the Storyboard yet, I am certain there must be a way, but for now we call our custom method to return the first view controller we want the user to see. Something that confuses me here is that it wants an array of view controllers, yet we only pass a single one.  This is consistent with the Apple example.  Evidently, we are leaving it to our datasource logic to dictate the next controller.  This is in line with how many other platforms do similar data sourcing operations.

I will be honest, I am not entirely sure what the last two lines are doing.  But they seem to be required and are copied directly from Apple’s example.

That is it.  Everything should be working now.  I have listed some common problem points below if you have trouble:

I get no UI when I start

Check that you are specified the “Initial View Controller” on one of your view controllers

My transition curls instead of scrolling, like a book

You need to set the transition type to Scroll.  See the very end of point 2.

I see my initial view but I can’t scroll

Check the logic in your page controller datasource, make sure it is incrementing properly.  Also, you HAVE to make sure the Storyboard Ids are set properly otherwise you will not be able to find the view controllers from the storyboard.  This will more than likely cause your application to crash instead of simply not working

Leave a comment if there are any additional problems

Visual Studio Online + Git with XCode

Recently a friend of mine and myself decided to embark on a new project we are calling ‘OneList’.  After much deliberation we decided to use iOS for the initial release, it would be my first serious iOS application and I also decided to make it the first project where I use Git as it should be used, from the command line.

I like GitHub, but it really does lack the feature that Visual Studio Online has for Scrum.  The ability to use Git on Visual Studio Online and still get all the project management features of TFS is a huge plus, so we decided that would be the ideal place to store our code.  However, it also meant that I would have to connect XCode to Visual Studio Online through Git.  After doing some research I discovered two options for doing this: TFS Git and pure Git.

This is the same no matter what

No matter which approach you take you will need to ensure that a Git repository exists locally before you attempt to push to a remote repository.  Doing this in XCode is quite easy.  Make sure you have Git installed (here), this will also add it to your path.  When you create your project make sure to check the box indicating you wish to use Git for source control:

ios_screen1

ios_screen2

ios_screen3 

This will create your project and call git init on the directory, initializing the local git repository.  This works great as a starting point for a new project.  With an existing project, open a Terminal window, cd to the project root directory and run git init.

Here is where things get different

The path you pick here is going to depend on how you create your project using TFS online.  You would think that you would simply pick the Git variant and be done with it, not not so.

Approach 1: Its Git, but really its TFS

The Visual Studio Online site does not make this clear, but their recommended approach is to use Git with TFS.  See if you hit their instructions for using Git (http://tfs.visualstudio.com/en-us/learn/code/use-git-and-xcode-with-tfs/) they recommend using this tool: http://gittf.codeplex.com/.  However, if you check their instructions carefully you will see that you are actually creating your project to use TFS and not Git.  This is essentially the “half Git” approach, cause you are only using Git locally, but TFS in the cloud.  Here are the steps:

  1. Use ‘New Team Project’ (the blue button) when you setup your project
  2. Make SURE to select ‘Team Foundation Version Control’ for Version Control (this is where I got messed up cause you would think to select Git)
  3. Look for your email address and access your Profile.  Look for the ‘Credentials” link
  4. Enable ‘Alternate Credentials’ and give yourself a custom username and password.  This is what we will use when accessing the server below
  5. Download git tf and make sure its appended to your $PATH.  If you are like me and already have Java you can ignore those instructions

Once you get it installed usage is quite easy.  Configure your project URL using git tf configure, here is an example of the one I used for OneListTest:

git tf configure –f https://farrellsoft.visualstudio.com $/OneListTest

Basically, give it the URL to your visual studio collection root and then tell it which team project to use.  This gets you configured.

As far as development goes, do things as normal using git locally to populate your local repository.  When you ready to push, you perform a checkin

git tf checkin

This will “push” your changes to the remote URL that you configured earlier.  Remember to provide your alternate credentials when prompted.  This approach is effectively “half Git” since you really arent using git all the way around.  The git tf wrapper is acting as a bridge between TFS and Git and performing the translation so if you are used to TFS you can use roughly the same terminology.

This works great if you have an existing TFS project in the cloud and want to use Git locally, but if your like me and want to fully leverage Git, you need to go a different route.

Approach 2: It really is Git

So given that the first approach used the “blue button” and was actually TFS on the server, you can guess where this approach will take us, yup the ‘Red Button’ or ‘New Team Project + Git’.  This time make sure that ‘Git’ is selected as the Version Control option (though it should default to this).

Ok, now that we have that setup, we need to configure our remote so we have somewhere to push to.  Without diving too much into Git and its terminology, remember that you keep a repository locally with your changes and then when you are ready you “push” to a remote/shared repository.  This is what is meant by “distributed source control”.  To add a remote you do something like the following:

git remote add

Remote name is the shortcut name of your remote repository, you will use this when you initiate a “push”.  The Url is the actually Git repository which will be committed against.  For example:

git remote add OneListTest https://farrellsoft.visualstudio.com/DefaultCollection/OneListGit

Confirm that your remote was added using git remote

Now you are set to go, work with your local repository like normal and when you are ready call git push to push your work to the remote/shared repository.

Side note, I do not recall entering my credentials when I did a push which felt weird to me.  Not sure if there is a security setting somewhere that I forgot or if I entered it somewhere else and it remembered.  Be careful of this, especially if you have secure source code.

Conclusion

In this article I walked through the basics of putting an XCode project, both existing and new under source control using Git.  I then described two approaches whereby these source control bases could be managed using Visual Studio Online, one using TFS under the hood and the other purely using Git.  I find Git quite fascinating and intriguing.  I choose to use Visual Studio Online over GitHub due to the greater number of features relating to Scrum based project management available through Visual Studio Online

Creating custom backgrounds for Windows Phone Push Tiles

As Windows Phone 7 is still around and will be around for sometime I thought it proper to talk about one of the most useful techniques that developers employ to customize their live tiles.

First let’s start with what Microsoft gives you for the front of the tile:

BasicTileFront

Personally I hate this look, especially the way the notifications are displayed.  After all the work that is put into creating an app experience, being forced to go with this look just seems wrong.  Thankfully, you are not forced to use this and, in fact, most developers seem to avoid it, aside from Facebook, but their app has more things wrong with it than just the notifications.

So how can we adjust this?  The answer lies in the background URI that you are allowed to specify as part of the push XML, turns out it doesnt have to point to a real image.  Here is a sample from the Codemash app:

<?xml version=\"1.0\" encoding=\"utf-8\"?>
<wp:Notification xmlns:wp=\"WPNotification\">
   <wp:Tile>
      <wp:BackgroundImage>
         http://localhost/handlers/WP7Background.ashx?count=1
      </wp:BackgroundImage>
   </wp:Tile>
</wp:Notification>

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

Notice that I am specifying an ASHX handler.  Really it can be anything so long as what is return is perceived as an image.  Here is the code for the handler:

public void ProcessRequest(HttpContext context)
{
   string basePath = context.Server.MapPath("Images/wp7");
   int count = context.Request.QueryString["count"].AsInt();
   if (count > 0)
   {
      string filename = GetFilename(count);
      string filePath = Path.Combine(basePath, filename);
      if (!File.Exists(filePath))
      {
         CreateNotificationTile(basePath, count);
      }

     context.Response.ContentType = "image/png";
     context.Response.WriteFile(Path.Combine(basePath, GetFilename(count)));
     context.Response.Flush();
   }
} private void CreateNotificationTile(string basePath, int count) { const string template_name = "phone7_template.png"; using (var srcTemplate = new Bitmap(Path.Combine(basePath, template_name))) { using (var graphics = Graphics.FromImage(srcTemplate)) { var font = new Font("Arial", 35f, GraphicsUnit.Point); var brush = new SolidBrush(Color.White); graphics.DrawString(count.ToString(), font, brush, 105, 60); } srcTemplate.Save(Path.Combine(basePath, GetFilename(count))); } }

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

What I am doing here is opening an existing image and drawing a number to it based on what I received for the count, I think save that image and return the file’s byte stream.  Along with the forced content type makes the receiver (the phone) think this is an image and display it.

For the sake of efficiency, the reason I save the created image is so I can simply return it later instead of creating the image each time.  The result is if I make a request to this handler with count = 1, I get the following image:

1

Remember, that there is a limit to how long a push notification will wait for its background to download is 1 minute and the returned tile cannot exceed a size of 80kb.  These are hard limits by Microsoft and they make sense.

What about the back content?

The back content can take the same approach, really anywhere that allows specification of a URI for the background can be manipulated using this approach.

Can I do this for things other than numbers?

Yes.  Take an app like Weatherflow which will actually send you an image representative of the weather in your area.  In fact, people will also send color information based on the current theme the phone is using so the tile background can be adjusted to match.  This is why this approach is so popular is the immense amount of creativity it makes available.

What about Windows Phone 8?

This approach remains useful in Phone 8 through the Cycle and Flip tile templates.  I am certain you could use the technique with the Iconic template, but I am not sure it would make sense.  But as I said, really anywhere there is a URI specified allows you to use this technique.  Its nothing especially new, we have been using it on the web for years.

Final Thoughts

I really love this technique and regularly use it in my Windows Phone apps.  I think Microsoft recognized the limitation the previous tile formats placed on developers and resolved it by offering the additional templates: Iconic, Flip, and Cycle.  These new templates certainly allow for more creativity, but specifying static images doesn’t always make sense, and in the cases where they don’t, it is nice to have this technique in your back pocket.

Codemash in Review

Finally returned to Chicago today after spending party of the week attending Codemash 2013.  Wow what a time, hats off to Brian Prince, Jim Holmes, Jason Follas, the .NET Rocks guys, and everyone who else who helped organize it, it seems to get better every year I go.

This Codemash was special for me mainly because it allowed me to see many of the people who I dont get to see as much anymore since moving from Michigan to Chicago.  Guys like Mike Eaton, Dennis Burton, Rob Gibbens, Chris Woodruff, David Girard and many more.  Conversations with them and the chance to hang out are simply special.

I really tried to stay away from sessions this year regarding Windows 8 or Windows Phone mainly because I have had so much exposure to it, that its not really something I can learn much more about.  Instead I focused on things like SignalR and AngularJS.  I even got to meet the legendary Jon Skeet in a session that made the members of the Microsoft language team who were present cringe, some of the craziest stuff done with .NET that I have ever seen.  And I got to meet one of the guys who I look up to tremendously, Richard Campbell of .NET Rocks.  The sessions were just so amazing and I loved the people and the parties.  Codemash quite simply rocked, nothing else need be said.

One of the other reasons that Codemash was exciting for me this year was my app.  I decided to take a different approach to writing a conference app this year.  In the past at conferences I have seen the shortcomings of apps designed on a “get info” model, where the user has to get or refresh the data.  This ends up being a problem due to the poor network connectivity at these conferences.  I decided to copy the Codemash REST API and provide an additional API to get changes to the schedule.  Users of my apps would then get notified when changes exist via Push.  While the changes would still have to be downloaded via the network, it would me much smaller and more targeted, thus be a much lighter request.

The result of this pilot was immense, people absolutely loved the idea.  So much that, though I screwed up the scrolling on the app due to a XAML mistake, people were downloading it and keeping it simply to know when stuff changed.  I think if the app had been A) released on time and B) not had the scrolling problem it would’ve received many more downloads.

But it being a pilot there were still problems.  Two times updates to the Codemash schedule (especially around Open Spaces) caused the change update process to crash.  This revealed to me that the applying of changes needed to be hardened so as not to bring down the entire app when a problem occurred, even though the problem was born external to the system.  But this is a relatively easy fix to make and it will be made for the next conference.

Speaking of conferences, I participated in a great open spaces section with Rob Gibbens, the masters of the Codemash REST API, and the organizing leaders for the St. Louis Day of .NET and Codeapolouza.  Their insights were very helpful and appreciated in helping us forge our idea to create a system whereby conference data APIs could be standardized.  I think this needs to happens, most geeks have smartphones, why should people be using a book to view session data.  The amount of things you could do with such a tool are limitless both to attendees and organizers.  Really cant wait to work more on the idea.