Our DNA is written in Swift

Announcing BarCodeKit

iOS7 will have the ability to scan 1D and 2D bar codes built-in. The same is true for generating 2D bar codes. Which begs the question why Apple opted to omit support for creating 1D bar codes. (rdar://14694904)

One second hand explanation I heard was that laser-based scanners might have trouble reading 1D codes from the screen of an iPhone, whereas 2D codes require a camera anyway and therefore can be easily scanned even from a display.

While this explains the omission to a certain degree, I don’t buy it. I can think of many scenarios where you would want to print a 1D bar code, or put it into a PDF that is supposed to printed. Also, as CCD-based scanners become more prevalent they will soon be available in larger numbers than laser-based scanners.

In short, I am seeing a niche that is not being served. Thus I’m announcing BarCodeKit.

BarCodeKit is supposed to allow for generating 1D bar codes for whatever use you might have for them in your apps.

Of course there are other libraries. Jeff LaMarche famously created CocoaBarCodes, which was last updated in May 2009. As you can see from the code it is targeting OS X. There is NetShade’s fork of this with some improvements, but abandoned in January 2013, which a long to do list. There are several severe issues with these two projects, for the most part they are Mac-only. Netshade removed the caption printing capability to make it iOS compatible, but never fixed that. And it doesn’t do ARC. And it is in much need of a ground-up rewrite. And so much more …

I got the fork to run on my iOS device, but it didn’t even produce correct codes. This is where my research stopped.

So I decided to start BarCodeKit and structure the whole thing in a way that is easy to understand and extend. I like to re-invent the wheel wherever feasible if it teaches me something and the outcome is better than the original wheel. Better insofar as that it is using modern object-oriented technologies, ARC, is platform-independent and simply the only thing you want to use for the purpose.

What Works

At the time of this writing I have the most basic bar code types done. Those include the ones that are used to represent products codes on physical products. Code 39 I found in use on a Netgear product label where it specifies MAC-address, serial number and product code.

EAN-13 / UPC-A

EAN13 generated with BarCodeKit


EAN8 generated with BarCodeKit


UPC-E generated with BarCodeKit


Code39 generated with BarCodeKit

Project Structure

I structured the codes around individual “code characters” which are a pattern of bars described by a bit string. All characters derive some basic functionality from BCKCodeCharacter. All codes share BCKCode as root.

BarCodeKit Project Structure

All characters know what pattern of bits (1 for bar, 0 for space) is representing them. This enables all drawing to be BCKCode.

From implementing what we got so far I learned that there are several different things people might want to customize for output of their bars. Because of this I didn’t implement a fixed way to draw them, but allow the user to pass rendering options. The codes are model objects and don’t deal with views, instead they have a method sizeWithOptions: and renderInContext:options: that allows you either provide a PDF or a bitmap context to draw the bar code into.

For example to create a bitmap of code you would use this code, provided in UIImage (BarCodeKit) category.

+ (UIImage *)imageWithBarCode:(BCKCode *)barCode options:(NSDictionary *)options
   CGSize neededSize = [barCode sizeWithRenderOptions:options];
   UIGraphicsBeginImageContextWithOptions(neededSize, NO, 0);
   CGContextRef context = UIGraphicsGetCurrentContext();
   [barCode renderInContext:context options:options];
   UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
   return image;

The reason for this approach is that typically a size of the output bar code is related to the width of the bars. If you make the bar width thicker, then whole code would grow in required size. If you want a larger bitmap you would increase the bar width multiplier. Also the EAN variants typically have a standard aspect ratio which increases the needed size, whereas Code 39 you normally want to have with a fixed height.

So far these options are implemented:

  • BCKCodeDrawingBarScaleOption: Multiplier for the bar width (default 1)
  • BCKCodeDrawingPrintCaptionOption: Whether the code caption should be printed (default NO)
  • BCKCodeDrawingMarkerBarsOverlapCaptionPercentOption: How many percent of the caption height are covered by elongated marker bars (default 1.0)
  • BCKCodeDrawingFillEmptyQuietZonesOption: Whether quiet zones should be filled with angle brackes (default NO)
  • BCKCodeDrawingDebugOption: Whether the caption areas should be tinted for debugging (default NO)

As time goes one I am certain that additional options will become necessary, like to set a fixed bar height or specify colors. Those will depend on the use cases that developers will want to use it for.

How to Use

BarCodeKit is very simple to implement. You create an instance of the code you want to generate and then call the above mentioned category method.

NSDictionary *options = @{BCKCodeDrawingBarScaleOption: @(2)};
BCKEAN13Code *code = [[BCKEAN13Code alloc] initWithContent:@"9780596516178"];
imageView.image = [UIImage imageWithBarCode:code options:options];

Of course there are many more things to do with this, like to add proper unit tests and additional codes, like Code128. But again, those will have to largely depend on public interest in this framework.

I have implemented a simple demo app which lets you play with some of the options to see their effect.

BarCodeKit Demo App

As work progresses on BarCodeKit this might change quite a bit, to accommodate additional codes and code-specific options.

Update: Documentation is now available.

The Future

In the near term future BarCodeKit will remain closed-source to preserve the competitive advantage that it provides to people who are willing to spend a little money on acquiring a license. Introductory price will be 150 Euros, which will give you full access to the private git repository where it is being developed.

If you are interested in adding features (i.e. additional bar codes) I would waive the fee in exchange for your contributions. It largly depends on the interest of the community in which direction this project will evolve. We will see, however for now I need to make a little bit of money with it.

Either way, please contact me if you have a project that would benefit of BarCodeKit.

Tagged as:

Categories: Parts