AI In Your Windows Phone Apps? Elementary, My Dear Watson, pt. 2

In part 1, we talked about IBM’s Watson, BlueMix and how to setup a new cloud app to be able to access Watson’s APIs.

If you haven’t already done so, now would be a great time to sign up for your IBM Bluemix account.

In part 2 we are going to take a closer look at Watson’s Question and Answer service and build a Windows Phone 8.1 app to allow us to ask Watson some questions and see what he comes up with.

To get started, let go take a look at the API reference for the Watson Question and Answer service. We will be focusing on the /v1/question/{id} method which is only accessible via POST requests.

Nero Wishes He Was This Good

As with so many great stories, the story of Nero fiddling while Rome burned is much more fiction than fact. But Telerik’s Fiddler is every bit as good as you may have heard. We’re going to use Fiddler to construct some test POST requests in order to get a sample of the JSON returned by the Question and Answer service. With this JSON data we’ll use the excellent Web Essentials Visual Studio add-in to create models for use within our app.

When you startup Fiddler, it will immediately start tracking all of your outbound HTTP traffic. We don’t need that so click File and uncheck “Capture Traffic”. Next click the Capture button on the menu and then click “Remove All”. This will clear out the sessions window.

To begin creating our request, click on the “Composer” tab. You should now see something like this:

Fiddler Composer

Fiddler Composer

Update your request to look like this:

Our API request

Our API request

The only thing you need to change is your Authorization token. To do this, grab your service username/password as we discussed in step 1. In Fiddler, click Tools –> Text Wizard. In the text wizard, enter your username/password in this format: username:password then click the To Base64 radio button, and there’s your authorization string. Once you have the request ready, just click the “Execute” button. If everything went well you should now see something like this in the sessions list:

Capture

If the result status is 200 then everything worked, otherwise there was an issue somewhere along the way. Either way, you need to click on that line and then click the “Inspectors” tab to get a closer look. From the inspectors tab you have a number of ways of viewing the response. There is a plain text view, XML view, JSON view, etc. We are most interested in the Text and JSON views. If you received an error, you should be able to see the details of the error here and go back and fix your request accordingly.

YMMV Framework

And now we finally get to spend some time in Visual Studio. If you don’t already have Web Essentials installed, go to Tools –> Extensions and Updates –> Visual Studio Gallery and search for Web Essentials.  Download…install…restart… We’ll wait.

Now let’s start a new Windows Phone 8.1 project (Alternatively, you can just download the current solution from my GitHub account). I used the blank app for Windows Phone template, but you can use any of the templates, or Windows Phone Silverlight, or even a Windows Phone 8 project if you want. I always prefer to have a good separation of my code no matter how small the project may be so let’s also add a new PCL project as well.

Web Essentials has a handy little feature that makes it much easier for working with web APIs that return data in XML or JSON.  Let’s go back to Fiddler and from the Text view of our response, copy the entire JSON response.

Forest Gump Was Right

Now that we have the JSON response on our clipboard, let’s add a new folder called “Models” to our PCL project. Next we’ll add a new class to the Models folder called AskWatsonResponse.cs.

Place your cursor inside the class’ namespace declaration and under your Edit menu, you

Web Essentials generated classes

Web Essentials generated classes

should now see an option added by Web Essentials called “Paste Special”, with options to either Paste JSON as classes or Paste XML as classes. Since we copied JSON data, we’ll select the Paste JSON option. Web Essentials has magically generated classes corresponding to the JSON data we had on the clipboard. This is a great feature for getting models created quickly and easily when you are working with a web API. You should now have something like the image to the right.

Web APIs are like a box of chocolate – you never know what you are going to get. And if you look closely you will notice a couple of interesting things with the generated classes. Namely the Rootobject class and the Class1 class. These are here because Web Essentials found JSON objects at the beginning of the response that were not named. There’s nothing technically wrong with that, so that’s fine until we ask JSON.net to deserialize a JSON response string into this class structure. It’s kind of hard to map an object or property that doesn’t have a name in the JSON to a class or property.

If you take a look at the raw JSON, you will see that the first named object is named “question” and so the Question class is really what we are going to concern ourselves with in the generated classes.  We’ll discuss deserializing our responses from the Watson service a bit more in a few minutes.

Where’d You Go To School? UI?

Let’s build a quick UI to use for asking questions of Watson. I will be referring to the 3Windows Phone 8.1 XAML controls, but you can just as easily build a similar interface for Windows Phone 8.1 Silverlight or using 3rd party controls from the likes of Telerik or Infragistics, etc.

Our UI is just a ComboBox for selecting the category we are asking about, a TextBox for entering the question, a Button to send our question to Watson, a ProgressBar so the user knows we are doing something, and finally a ListView to display the results.

Currently, Watson only supports searching against two categories: Healthcare and Travel, so the Category ComboBox is just hard-coded with these two options.

To get a full look at the xaml and code-behind for the UI, just pull down the AskWatson Git

The Missing Link

So we have a model class and we have a UI, all we need now is something to tie it all together. Let’s add a new class to our PCL and call it AskWatsonService. This class will contain all the methods for calling out to the Watson services, retrieving data and deserializing to our own model classes.

To start off with, the AskWatsonService class will have two methods. A public method representing the Watson Question and Answer service:

AskWatson method

AskWatson method

And a generic private method that takes care of creating the actual service request and returning the JSON from the API to our public method:

_GetJsonResponse method

_GetJsonResponse method

As we mentioned earlier, there were some, um, minor issues with the JSON being returned by the API that makes it impossible for us to do a simple deserialization with code such as the following:

return JsonConvert.DeserializeObject<Models.Rootobject>(jsonResponse);

Instead we first need to parse the JSON into an array of JSON.net JToken objects using the JArray.Parse method. Once we have the JToken array we can then use the DeserializeObject method on the first item in the array which contains the question object and return the model back to the UI.

What Now?

To get a closer look at the code and how it works, you can checkout the AskWatson Git repository. If you want the most current version of the demo app on your Windows Phone 8.1 device, you can download the Ask Watson app from the store. And if you want to play around with the Watson services for yourself, signup for an IBM Bluemix account.

What’s Next?

In part 3 we will take a look at Watson’s User Modeling service and analyze the personal characteristics of some of our favorite people.

Advertisements

About Andrew Long

Web developer, Windows Phone developer: http://bit.ly/andrewlongWP, IBM Bluemix Evangelist: http://bit.ly/bluemixtrial
This entry was posted in Windows Phone, WP8 and tagged , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s