2012-11-08

Barcodes in iOS

Recently I’ve been investigating methods for getting iOS apps to read one and two dimensional barcodes. There’s a huge variety of formats, but the three I’m mainly interested in are UPCA and EAN-13 (linear barcodes you’ll find on boxes in shops) and PDF417 (matrix barcodes you’ll find on some US driving licences).

There appear to be three main competitors for your attention if you’re trying to read two-dimensional barcodes in an iOS app:

ZXing is an open-source offering that supports a smorgasbord of formats for a variety of platforms and languages, including iOS, Android, Java, C#, ActionScript and others. Unfortunately, its PDF417 support is listed as “alpha quality” and the iOS port only supports QR codes (another matrix format). The iOS port hasn’t been updated in about 3 years, so ZXing is out.

Manatee Works is a closed-source library that claims to be smaller and more efficient than ZXing. It supports Windows, Android and iOS, and supports all of the bar codes I’m interested in. Looks good! How much does it cost? And can I see some code so I get an idea of how well the API was put together? No. No I can’t.

Manatee Works appears to be one of those companies that believes ardently that keeping its prices secret will encourage people to contact its sales team so they can presumably engage in the hard sell. Either that, or it’s like one of those restaurants that don’t put prices on the menus because, if you have to ask how much it costs, you probably can’t afford it. In any case, their product does indeed cost more than I’d pay.

Lastly, there’s SD-Toolkit. Again, they support multiple platforms: Windows, Android, iOS, Mac OSX and Linux, and again it supports all of the barcodes I need. Their relatively reasonable prices are published on their website and they even provide a trial SDK. My only issue with SD-Toolkit was that their trial SDK doesn’t yet support the armv7s architecture used in the iPhone 5.

If you’re trying to include a barcode reader in your iOS app, these are your options:

  • An extremely limited open-source effort that’s been abandoned;
  • An extremely expensive closed-source library that you can’t see until you talk to the sales team;
  • A more reasonably-priced closed-source library, with a trial SDK, that’s a little behind the times.

At this point I came up with an alternative solution: don’t try to read barcodes on an iOS device at all. Instead:

  • Grab a photo of the barcode using the phone;
  • Rotate, scale, crop and compress the image down to ~40K;
  • Post the image to a web server running a barcode reader SDK behind a RESTful web service;
  • Perform all of the barcode parsing on the web server;
  • Return the parsed data as JSON objects to the iOS device.

The downsides to this are obvious. Barcode parsing will only work on an iOS device that has an internet connection, and parsing times will include data transmission time. However, the advantages are compelling. The average web server is so much faster than an iPhone that the time taken to transmit in both directions and decode via a web service appears to be no longer than the time to parse directly on an iPhone. ZXing becomes an option again if you’re a Java shop. If you can’t use ZXing, you should be able to find an SDK for your prefered language for - at most - the cost of Manatee Works’ library, but it will work on all devices. Yep, a web service will work with Android, iOS, Windows, Linux, BSD or anything else with an internet connection.

That’s the option I’ve plumped for. It’s working nicely so far. The most troublesome part was rotating, scaling and cropping the images from the iOS camera correctly on all iOS devices.

One final note: Don’t bother trying to read barcodes on an iOS device that doesn’t have an autofocusing camera. It just doesn’t work reliably. Stick to the iPhone 3GS+, iPod Touch 5g+ or the iPad 3+.