11 thoughts
last posted Feb. 20, 2017, 12:04 a.m.
get stream as: markdown or atom

It turns out that the cordova barcode scanner plugin supports different sets of barcode formats, depending on the host platform.

Specifically, android vs iOS:


  • UPC_E
  • UPC_A
  • EAN_8
  • EAN_13
  • CODE_128
  • CODE_39
  • CODE_93
  • ITF
  • RSS14
  • PDF417


  • UPC_E
  • UPC_A
  • EAN_8
  • EAN_13
  • CODE_128
  • CODE_39
  • ITF

The project I've inherited: meant to read CODABAR labels on Android and iOS...

It seems this difference in formats stems from the way the android version uses the official java ZXing library.

The iOS version uses an ancient C++ port of ZXing, which didn't yet include these formats.


It seems this is a legacy inherited from ancient phonegap plugins, and hasn't been updated since. Likely since the C++ port has been deprecated and removed from the official ZXing project, it might've simply become a "too hard for the moment" problem.

Looks like most barcode scanning plugins for cordova are forks of this, so they all carry the same issue.

The plugin doesn't use a recent version of the library, for iOS. It uses an "all in one" version of the ZXing source code (see "zxing-all-in-one.h & zxing-all-in-one.cpp", to make building less complicated. Unfortunately it makes updating to a new version a bit more complicated.

The plugin project itself is a fork of an earlier plugin project. Somewhere in the process of forking, the scripts / docs on how the authors generated the "all in one" zxing files was removed...

The ancient, deprecated plugin project which created these all-in-one files is here:

It includes a makefile and a custom python script to create the all in one files, in the build directory.


Naturally, this doesn't appear to work out of the box on the still-community-supported zxing-cpp port (which picks up from the last c++ commit in the official project, before it was removed).


Options at the moment:

  1. Work through errors, generate a new "all-in-one" version of the zxing-cpp files,

  2. Attempt to reference the zxing-cpp project without munging into an all-in-one version. Will need further updates to the plugin project to support this, or

  3. Find an elusive alternate cordova barcode scanner plugin that works for both android & iOS, that supports all the formats needed (mainly CODE_128 & CODABAR) on both platforms.

For 1 & 2, they both need rebuilds of the plugin itself... I need to level-up in the ways of cordova/phonegap & and learn about that.


My preferred (tic tok, tic tok) option 3 hasn't worked out.

So actually went with a fourth option: drop in the Objective C port of ZXing, instead of using the C++ library.

Seemed to be an easier path -- as far as integrating with the rest of the cordova plugin.


All of these scanning plugins, on iOS, seem to rely on the AV Foundation framework to access the camera.

To set up the camera for scanning barcodes, you need to:

  1. Get a AVCaptureDeviceInput reference to get camera input, and

  2. Declare the AVCaptureMetadataOutput details of camera frames you're interested in receiving.

As part of the setup of AVCaptureMetadataOutput, you need to flag what barcode formats the AV Foundation functions should look for before it passes the images back to your code. If the format isn't on the list of supported types, don't expect any images.

Guess which format AV Foundation doesn't list.

So, while zxing supports Codabar, it's not being sent the camera frames since AVCaptureMetadataOutput doesn't recognise it.

There doesn't appear to be a way to tell this framework "just send me the damn frames, and I'll parse the thing myself".

I suppose this is meant to help performance, and not have random apps slowing the phone down trying to chew through a massive queue of images to process, but that doesn't really help me much.

May need to find alternative way of fetching camera frames, but it's never good news, or a good smell, when you need to start fighting the platform.


Perhaps this is why no-one has bothered updating the "all-in-one" c++ zxing version in the existing plugin...

"AV Foundation says no."


Then again, very likely missing something. Learning cordova plugin development, while tackling Objective C for the first time.

Back to the docs...


Ah. I'm a goose.

The codebase still has references to the zxing calls, but swapped out using it without removing the old code, which led me down the wrong path.

Before it changed, it was using AVCaptureVideoDataOutput to process the frames itself.

Then it changed to using AVCaptureMetadataOutput instead, delegating the image processing to AV Foundation instead of zxing.

Looks like to add codabar support, I may need to reverse this, since AV Foundation doesn't do codabar.

Not ideal, since I imagine the original devs had a good reason for swapping it out in the first place...

The git commit links to a ticket with the whys and wherefores.


Their linked issue seems to mainly be a problem with memory leaks in the (ancient) zxing c++ all-in-one they were using.

Could be that might not be a problem with the objective c port I've started integrating (seems quite an active project, so hopefully if folks were having problems, they'd be complaining...).

Will give it a whirl and see how it goes.


There a few ways to add plugins that are under development.

  1. Specific git hash, against an accessible repo:

    meteor add cordova:com.phonegap.plugins.facebookconnect@

  2. From the local file system:

    meteor add cordova:cordova-plugin-underdevelopment@file://../plugins/cordova-plugin-underdevelopment

When adding from the git repo, the plugin files are copied to the local build directory, and all the processors/compilers do their thing.

It seems when added from the local filesystem, the plugin isn't actually copied to your build. A symbolic link goes in instead, which mostly behaves the same way.

Only difference is in the generated XCode project.

The build doesn't create iOS binaries. Some licensing / tooling dramas, or something... Instead, an XCode project is created, and you fire up your copy of XCode, using your own developer certificates, etc, and compile that project yourself.

For the sym-linked version of the project, all the paths to your plugin's source files seem to be wrong. For "properly" copied plugins (eg. from the git repo), the XCode paths end up correct.

This screwed me up for so long...

When all else fails, fetch it from git.


So it seems to be working...

Was about ready to rage-quit, when I stumbled across a similar effort made prior to Xcode 8 & iOS 10 coming out and mucking up everyone.

They looked to be adapting the plugin code before they ripped out all their c++ zxing-all-in-one calls and replaced them with the AV Foundation metadata apis.

So I wasn't using those parts, since I was pretty much using the sample code from ZXingObjC.

However, the part that just wasn't coming together for me was the cordova plugin.xml file, which instructs cordova how to build the different versions of the plugin for each platform.

In the case of iOS, the plugin.xml instructs cordova how to assemble the Xcode project.

Most of the dually8/BarcodeScanner plugin.xml was a drop-in replacement for what I'd tried. Only needed 2 ZXingObjC files added to get it going, since they'd only been created in the months since their last update.

With the corrected plugin.xml, and referencing the plugin from its git repo (see an earlier comment why file:// refs are bad...), the Xcode project built successfully.

Had a couple of minor syntax errors in the Objective C changes I'd bashed in there, but other than that, my iOS device was suddenly, and somewhat surprisingly, scanning CODABAR barcodes.

Last hurdle will be to see if the memory leak / crashing issues that the original projects came across rear their heads. But, so far so good...