Pages

Saturday, December 21, 2013

Shrtr

Note: to read the background, and reasons for developing Shrtr for Windows Phone, see my main blog post.

Having decided to take up the DVLUP challenge (see post on my main blog), I sat down to write my URL shortening app, Shrtr.

Development environment

My first set of problems started with installing the development environment itself. WP8 SDK requires Windows 8 and higher (why W8? because Microsoft decided to take a page out of Apple's book of "Douchy tricks to drive sales of new technologies by limiting dev tools to new environments").

I already had a W8 partition on my trusty T400, which I upgraded to W8.1 Pro. (Side note: despite being over 5 years old, the Lenovo T400, with a fast SSD and 8GB of RAM, is a surprisingly snappy, reliable development machine). I installed VS 2013, but then hit the second snag: MS only allows installation of the WP emulator on processors that support a Hyper-V feature called SLAT (why? see "why W8?" above Update: I finally figured out why Hyper-V is used: the WP8 emulator is implemented as a separate virtual machine, which is very smart, and useful. However, I believe it can run on Windows 7 as well). This feature only exists in the 2 recent generation of Intel processors.  So I couldn't use an emulator in the development of the app. Luckily, I have a Lumia 620 on hand, and Visual Studio allows debugging on a device. It's a bit slower, but you get to experience the behavior of the final product earlier.

To complete the dev environment experience, I used Chocolatey (think of it as "apt-get for Windows") to install Git for Windows, and Paint.Net (which imho MS should have acquired and turned into the default Windows Paint app years ago). I also installed the latest version of Node and Node tools for VS (currently in alpha), to allow me to run both server and client.

Architecture

By design, the app allows you to type or paste a proper URL, select one of (currently 6 supported) shortening services, and get back a short URL. You will then be able to email/share/copy-paste the short URL, from within the app.

Most online shortening services have (some sort of) an API. It can be RESTful, or just a URL you GET or POST the long URL to. Some require that the long URL start with a protocol ('http'), some don't. Some require a developer key, some don't care. Some support custom ("vanity") URLs, and some don't.
I built an abstraction round the actual API calls, that externalizes a simple call, specifying service name, and long URL as parameters. This way I could easily add new shortening services with few parameters (URL, API method, how to parse the reply, key, should the URL start with protocol?).

Since I intended to add more features later (if anyone will be interested in the app), I immediately saw the need to break the app to a server and client components.

Client

The first version to Shrtr was a Phonegap cross-platform app, written entirely in JavaScript. It ran well on Android and iOS, so I downloaded the WP8 Phonegap template for VS, and attempted to copy-paste in my app. Despite claims of Phonegap working transparently on WP, I ran into several issues:
  1. Phonegap events are not completely supported on WP, breaking my code. Yes, there are workarounds, but I was hoping to having to deal with as few code changes as possible.
  2. The design that looks great on iOS and Android (Webkit-based browsers) just breaks on mobile IE.
  3. I ran into some cross-domain AJAX call issues.
My second attempt was to try the Javascript WP8 template provided in VS, and just shoe in the app logic. Things ran aground pretty quickly. Around that time I came to the realization (see Architecture) that the logic will be broken out to a server, so my third attempt at the app was to use the default WP8 template. I haven't touched XAML in a long while (since my happy .Net days in 2011), but returning to C# was easy, and VS is a helpful, rewarding dev environment.

Visual Studio now comes with NuGet built in. Think of NuGet like Node's NPM for VS. It easily installs installation external components and libraries from a repository, extending your project and development experience. I used it to install RestSharp - for easy consumption of my REST service, and Windows Phone Toolkit - added several phone controls, such as a versatile list control, and a highly configurable textbox. 

UI


Visual design of UI has never been my strong suite, so my single screen still looks like "My FIRST XAML", but it's functional, and it works (btw, if you think you can help me make it look nicer, please drop me a note or comment). 

Logic


After finishing the UI and tying all the events to their respective handlers, I wrote a couple of classes encapsulating the calls to the backend service, the service request and response, and used RestSharp to serialize/deserialize the request and response. Once you grasp the async calls Lambda syntax, it becomes easy to write and handle the service calls. And RestSharp makes reading/writing JSON a snap.

The app has basically 2 calls to the server:
  1. Get a list of shortening services to show in the services list.
  2. Shorten a provided URL, using a specified service.

Flow


You type/paste the long URL into the textbox. The length limit is displayed in the bottom right. You can select the service from the list control, or reuse the one you've selected before. You submit the call by hitting the little scissors on the right, or hitting Enter on the keyboard. Selecting a different service will resubmit the existing URL to the new service.

The short URL is displayed in a simple textbox. The app then uses the AppBar to expose the available actions the user can take with the shortened URL, using standard phone tasks.

I then added some local settings to allow saving the last service you've used for the next time. I may add some functionality around saving all the URL history - if anyone asks for it.

Server

My last 2 major projects were written in Node.js, using the Express framework, and I saw no reason to change a winning horse. Furthermore, since the logic for my original Phonegap app was written as Javascript classes, it was fairly easy to move them to server side code, without to many changes.

The server exports a RESTful service, accepting and returning JSON. It exposes 3 methods:
  1. A list of services supported.
  2. The shortening function, accepting service name and long URL.
  3. A ping service - allowing to check if the service is up.
I used the local Node server to test my app and debug on both ends. Chrome developer Tools is your friend here.

To quickly deploy and test a Node server, I use Heroku. After a short installation of their command line tool, provisioning the server is one line, and deploying is a mere git push command. I'm considering trying Microsoft Azure for my next project, but have yet to find out how to use it for free :).

After that, I added an index page, for people who just drop by, with links to the app. And yes, my HTML/CSS can stand some face lifting as well :).

Publishing the app

Publishing the app was rather easy. First, you need a developer account with Microsoft (which I got for free for a year - you can get it pretty easily, from either MS or Nokia). 
Clean your app from unnecessary resources. Fill the manifest XML correctly, making sure you pick up the right permissions - I only needed the ability to connect to network. 

Then, log into your developer account, upload the xap, fill in the data, make the right choices (supported sizes, languages and countries; good description of your app; good category), upload a couple of screen shots (easily taken on the device), and... wait. And wait. And wait for Microsoft to qualify your app. Since my app is quite simple, it went through certification the first time - your milage may vary.

After my app was published in the store, I had to "introduce" it to my Nokia DVLUP account, which took a couple more days. But eventually, I got the XP points for the challenge, and my award device is on its way!

Next steps

Since the logic now completely resides on the server side, I can add more shortening services at will, and I can add more clients. In fact, I did. 

Right now there's a Chrome extension in the Chrome web store, and in my free time (yeah right :)), I'm working on an Android app.

I'm hoping I can solicit some help in the UI department, that will make the app shine. But either way, I learned how to develop and publish a WP8 app the hard way, so the next one would be a snap.

Download links