Sunday, September 29, 2013

How to Add Barcode Scanning to your Web App using Xamarin

Recently I had a client who wanted to add barcode scanning capabilities to their web app. Their web app was already responsive thanks to Bootstrap but there isn't a convenient way to scan a bar code from mobile Safari or Chrome.

This turned out to be fairly trivial thanks to Xamarin and two components in their Component Store:
JsBridge - eases Native to Javascript communication
ZXing.Net.Mobile - handles the barcode scanning

Here are some screenshots of what the web app looks like when accessed via the iOS app:

One of the requirements of the bar code scanning was to not show the Scan button if the user is not using the native app. To do this I customize the UserAgent of the UIWebView and then do UserAgent sniffing on the server side to hide or show the Scan button.

You'll notice if you view the web app in a browser the Scan button is not displayed:
To enable this functionality in the iOS app we append a XamarinBarcodeSampleApp string to the default UserAgent of the UIWebView:

Then in the web app we do UserAgent sniffing for this string.

To wire up the Scan button we take advantage of JsBridge. The first thing we do is register the mt.js library. Secondly we listen for the scanComplete event which is triggered on the iOS app side. Thirdly we handle the Scan button click event and let the iOS side know about it by firing the scanBarcode event.

On the iOS side we need to enable JsBridge, then listen for the scanBarcode event. When scanBarcode is fired we display the ZXing.Net.Mobile scanner. If the user successfully scans a barcode we fire the scanComplete event and pass the barcode string as an event parameter.

The native / hybrid iOS app source code can be downloaded here:

The web app source code is here:

Final thoughts:

Xamarin tools are flexible enough to handle the requirements of the Web Application developer dipping their toes into native development. 

In fact the Xamarin tools work so nicely with UIWebView based web apps that I'd urge any developer looking at PhoneGap or Titanium to add Xamarin to your review list and avoid the limitations you may run into. 

For instance, I built a series of HTML5 based game for a client that play audio via Flash in a desktop browser. To make them work on an iPad I used Titanium to martial the audio playback to native code. At the time I figured Titanium was the best solution since the bulk of the code was already Javascript. I eventually ran into limitations with Titanium when I wanted to detect custom gestures and realized they don't have a 1 to 1 mapping with the iOS API like Xamarin does. I plan on porting this app to Xamarin in the near future to take advantage of more advanced native iOS functionality.

In a future blog post I will demonstrate how to use JsBridge and another library I wrote to martial audio calls to the native side like I did for those HTML5 games.

DISCLAIMER: I've been work full time for Xamarin for about 3 weeks as a web developer. The following experiences and opinions were developed during my 3 years as a freelance consultant.

Runaway Open Source Project - Lessons learned from developing HiSRC

TL;DR: Never reference files on servers you pay for in Open Source projects.

Today I noticed my monthly Amazon AWS bill was $20 more then normal.

Somehow 143GB of outbound transfer had happened in Sept. After an hour or two of investigation and deleting things out of buckets that may have caused it, I finally turned on logging and waited.

The logging revealed a plethora of requests for a file called 50K. I couldn't even remember what the file was there for. I thought maybe my account had been hacked. I finally Googled cdeutsch/50K and it immediately clicked.

Back in April of 2012 I helped developed the open source javascript library HiSRC. HiSRC checks for high resolution support and does a quick bandwidth test, if it detects either, high resolution images are served up dynamically on the client side.

Unfortunately I had placed the 50K test file in one of my Amazon S3 buckets and didn't change or remove that Url when making the library available publicly.

Fast forward to August 2013 and adoption of the HiSRC library has started to catch on by big names sites such as the following:

While it's flattering to have my nick cdeutsch appear in the source code of these sites, it's costing me money.

I've deleted the 50K file, but Amazon S3 will still charge me for the 403 errors that are now happening.

I'm waiting to hear back from Amazon on how to resolve this and am working on contacting the 3 biggest sites to get them to make the necessary changes.

Monday, June 17, 2013

What's The Best Structure for API Responses?

I learned something new while listening to Episode 12 of the Traffic and Weather podcast.

John Sheehan mentioned that when you return your XML or JSON from an API you should have an error envelop separate from the data envelop.

The main reason is if you're deserializing the output and mapping it to a class in a static language you can use error.message or error.code without namespace conflicts. This also gives you a consistent target for a given endpoint. John recommends avoiding returning one structure for success and another structure for error (something that I've been doing to date).

My take away is that John recommends structuring your return data like so:

  data: {
    id: 1,
    model: 'Mustang',
    make: 'Ford'
  error: null

  error: {
    code: 3,
    message: 'Car not found'

Continue reading to see the NOT RECOMMENDED way

The way I traditionally did it was without envelopes but the structure changes based on success vs error:

Success (the car object):
  id: 1,
  model: 'Mustang',
  make: 'Ford'
Error (the error object):
  code: 3,
  message: 'Car not found'

What I liked about my method is that you can deserialize directly to the class you want ("Car") without creating a wrapper class. For example, my way you don't have to have a class like this.

public class CarResponse 
  public Car Data { get; set; }
  public ApiError Error { get; set; }

The downside of my method is you have to do some extra work to parse errors into ApiError instead of Car.

I'm not 100% convinced I want to switch and have a bunch of response wrapper classes, but it's debatable whether there is another person more involved with APIs then John, so I'll probably be switching. ;)

Some questions I have for John's method (UPDATE: see comments for John's answers, my examples have been updated to reflect them).
  1. What's the recommendation for naming the envelop of the success data. Ex. "car" or always use something generic like "data"
  2. On success do you return the error envelop at all? If so, do you indicate a "no error" status code? Ex. "code: 0"

If you're working with APIs be sure to checkout John's excellent tool Runscope. It's good stuff.