Wednesday, July 20, 2011

YAGRAC

YAGRAC was a fun project that I started both because I wanted a better Goodreads experience on my Android device and because I wanted to learn the Android SDK. I learned quite a bit from that experience, and I am very happy with the result. A while back, Goodreads released their own official Android app. The features of the official app largely mirror those of YAGRAC. Since there is now an official app, and because I haven't had the time to continue development like I would prefer, I'm probably not going to do any more releases of YAGRAC. I'll leave it on the market and keep the source available. I'm thrilled if you used YAGRAC and found it useful. It was a great project for me to learn on.

Wednesday, April 6, 2011

Countdown Clock Live Wallpaper

As much as I hoped that my Round 2 entry for the Last Call for Google I/O 2011 would win me a ticket to the conference, it wasn't in the cards. Still, I'm making lemonade from lemons. I've modified my entry to display as a live wallpaper, and I've added a bit of configuration so that a user can set whatever target date they would like to count down to. The Countdown Clock Live Wallpaper is available on the Android Market.

Friday, April 1, 2011

White - Now Available for Android

I was listening to This Week in Tech on commute and heard Baratunde Thurston comment that he would like to see an app called White in response to COLOR. I was inspired, and today released White on the Android Market :-)

Download today! https://market.android.com/details?id=com.onesadjam.white

Thursday, March 17, 2011

Last Call for Google I/O

Google is running a series of contests this week to give away the last remaining tickets to the Google I/O developer conference. The 2011 conference sold out in record time, so for me, this is about the only way I'm going to have a chance to go. Yesterday was the start of the first challenge which focused on Android. Due to the time difference, the 30 minute "lightning" round 1 started during my normal lunch break, and I was able to quickly submit my answers. I was pleasantly surprised to receive an e-mail 30 minutes later informing me that I was one of 200 entrants to pass round 1 and move on to round 2.

For round 2, the objective was to create and submit an Android app that recreates the bouncing balls countdown clock seen on the Google I/O home page. Of course, today being St. Patrick's day, the clock is slightly changed to be formed of clover leaves blowing in the wind, but on non-holidays it is multicolored balls. Contestants had 22 hours to complete their app and submit, with the deadline being 9am pacific time this morning.

Now that the deadline has passed, I thought I would share my entry. I'm publishing both the source code and the APK file, so if you are curious how I made it, feel free to take a look.

Tuesday, August 31, 2010

YAGRAC

I've been wanting to learn how to develop for the Android platform, and I recently took some time to start a project to do just that. YAGRAC is Yet Another GoodReads Android Client. I've made the source code open source, so feel free to take a look or download the client and let me know what you think.

GoodReads is a social book reading service that I am a huge fan of. You can keep track of books that you have read, want to read, or are currently reading. Your friends can follow your list of books to see what you are up to. It is great for finding like-minded readers and discovering new books to enjoy. The GoodReads site is great, but when I'm away from my desk the mobile site leaves me wishing for more. GoodReads does not have an official app for iPhone or Android, so I though, why not make one myself! So far I have implemented the ability to read updates from friends, browse books on my own shelves or someone else's shelves, search for books, and review my list of social contacts (friends, followers, and following).

This project has proven to be a very good and effective learning opportunity. As I encounter interesting bits I will be sure to share them here.

Thursday, May 27, 2010

Creating a RESTful web service using WCF and JSON

There are a vast number of technologies to choose from for implementing a web application. You can choose Flash, Silverlight, Java, HTML, JavaScript, CSS, ASP.NET, PHP, and a host of others. Putting aside arguments for or against such an approach, let's examine how we might create a RESTful web service in WCF that accepts and emits JSON.
First, we need to create a project. Create a new ASP.NET web application. We can delete the Default.aspx file as we will not be using it.
Next, let's add a WCF service to our project. When naming this service, keep in mind that this is your access point to the resource that is represented in our RESTful interface. If we are talking about Widgets, we might want to name it WidgetManager.svc. This will create three files for us:
  • IWidgetManager.cs - The interface describing service contract
  • WidgetManager.svc - The web service definition (markup)
  • WidgetManager.svc.cs - The web service implementation
First examine the code for our contract.
using System.ServiceModel; namespace RESTfulWCF { [ServiceContract] public interface IWidgetManager { [OperationContract] void DoWork(); } }
We need to indicate that this web service will be using JSON for communicating to the client. To do that we modify the service method description.
[OperationContract] [WebInvoke( ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)] void DoWork();
Notice that we need to add a reference to System.ServiceModel.Web to our project and add a using statement to include the definition of the WebInvoke attribute. The next step is to indicate which of the REST actions (GET, PUT, POST, DELETE) the method will correspond to, and what REST URL format is used to call this method. Let's say that our web service method is intended to retrieve a list of all of the widgets known to the system.
[OperationContract] [WebInvoke( Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "Widgets")] void GetWidgets();
That completes the definition of our web service contract. Assuming our site is hosted at the root of localhost, it is accessed using a GET request against the URL http://localhost/WidgetManager.svc/Widgets and will respond with JSON. But wait, our response type is void. Let's define a complex data type to represent the properties of our widget and return a collection of those widgets from our method.
using System.Runtime.Serialization; namespace RESTfulWCF { [DataContract] public class Widget { [DataMember] public string Name { get; set; } [DataMember] public int SprocketSize { get; set; } [DataMember] public int CogCount { get; set; } } }
And we update our return type to be a collection of this type.
[OperationContract] [WebInvoke( Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "Widgets")] Widget[] GetWidgets();
We need the function to return at least one item in our array to effectively demonstrate this code. Open the WidgetManager.svc.cs code behind file and implement the web service.
using System.Collections.Generic; namespace RESTfulWCF { public class WidgetManager : IWidgetManager { public Widget[] GetWidgets() { List widgets = new List(); widgets.Add( new Widget { CogCount = 3, Name = "Widget Alpha", SprocketSize = 6 } ); return widgets.ToArray(); } } }
We now need to tweak our web.config file so that the web server and the class description are in sync. We could define our service behavior in the web.config as well, but in this case it is easier to use a factory to set that up on our behalf. Open the WidgetManager.svc file markup and add the Factory.
<%@ ServiceHost Language="C#" Debug="true" Service="RESTfulWCF.WidgetManager" CodeBehind="WidgetManager.svc.cs" Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>
We still need to make a change to our web.config, but now we only need to define the endpoint behavior.
<system.serviceModel> <behaviors> <endpointBehaviors> <behavior name="RESTfulWCF.WidgetManagerEndpointBehavior"> <webHttp/> </behavior> </endpointBehaviors> </behaviors> <services> <service name="RESTfulWCF.WidgetManager"> <endpoint address="" binding="webHttpBinding" behaviorConfiguration="RESTfulWCF.WidgetManagerEndpointBehavior" contract="RESTfulWCF.IWidgetManager"> </endpoint> </service> </services> </system.serviceModel>
That's all we need to get started with this simple example. Compile the project and run. You will see a webpage that indicates the endpoint was not found. This is because the default start page is the service file, rather than the REST URL. Modify the URL to http://localhost/WidgetManager.svc/Widgets and you will get the JSON result emitted back.
[{"CogCount":3,"Name":"Widget Alpha","SprocketSize":6}]
The next thing we will want to do is accept a parameter in the request. To do this, create a new service method that accepts a parameter, in our case the ID of the widget to return.
[OperationContract] [WebInvoke( Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "Widgets/{widgetId}")] Widget GetWidget(string widgetId);
And remember to implement the method in our code behind file.
public Widget GetWidget(string widgetId) { return new Widget { CogCount = 3, Name = widgetId, SprocketSize = 6 }; }
Now when we run the project and browse to the URL http://localhost/WebService.svc/Widgets/117 we see the output widget carries the name we supplied in the URL.
{"CogCount":3,"Name":"117","SprocketSize":6}
An important note here is that the parameters passed in to the web service method in this way must all be strings. A UriTemplate may contain as many parameters as you like, and may appear anywhere in the URI. So a URI template of 'Widgets/{widgetId}/Cogs/{cogId}/Color' is completely acceptable.
This is just scratching the surface though, as we still haven't touched on the other three REST operations (PUT, POST, and DELETE). There are a number of options on the data contract attributes that allow you to modify the names of the JSON elements, as well as the order they appear in the JSON string. Source code for the example in this post is available here:

Friday, May 21, 2010

Indy Tech Fest 2010 Slides

Click the image above to download my slide deck for "Getting Started with Online Mapping Services" presented at Indy Tech Fest 2010.