A Certain Minimal QR Scanner iPhone app
A QR Code is similar to a barcode, except it contains more information and looks like a pixellated square Rorschach test.
There are a number of free QR readers in the appstore like NeoReader and RedLaser. I especially like the scanning GUI for RedLaser, which seems more streamlined than any of the apps I have tried.
A number of these apps use the open-source ZXing ("Zebra Crossing") scanner library. The library is in Java but has a number of ports which include iPhone.
To start things off, you need to download or checkout the source. Create a new "View-Based Application" project in Xcode. Inside the iphone
folder of the source, follow the README
on how to include the ZXingWidget
project into yours.
Pay attention to the instructions, especially the direct dependency, header search path and the fact the file with the ZXing has to be a .mm
instead of .m
. If it does not build, you're probably missing something. You can look at the sample projects to see how they include the widget.
One last thing before moving on to the code, put the beep-beep.aiff
file from the ScanTest project into your project. This is to get audio confirmation of a scan.
Inside the sole viewController
of your project:
#import "ZXingWidgetController.h" #import "QRCodeReader.h" #import "ResultParser.h" #import "URLResultParser.h" #import "ResultAction.h" - (void)viewDidLoad { [super viewDidLoad]; [ResultParser registerResultParserClass:[URLResultParser class]]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; ZXingWidgetController *widController = [[ZXingWidgetController alloc] initWithDelegate:self showCancel:NO OneDMode:NO]; QRCodeReader *qrcodeReader = [[QRCodeReader alloc] init]; NSSet *readers = [[NSSet alloc] initWithObjects:qrcodeReader,nil]; [qrcodeReader release]; widController.readers = readers; [readers release]; NSBundle *mainBundle = [NSBundle mainBundle]; widController.soundToPlay = [NSURL fileURLWithPath:[mainBundle pathForResource:@"beep-beep" ofType:@"aiff"] isDirectory:NO]; [self presentModalViewController:widController animated:YES]; [widController release]; } #pragma mark - #pragma mark ZXingDelegateMethods - (void)zxingController:(ZXingWidgetController*)controller didScanResult:(NSString *)resultString { [self dismissModalViewControllerAnimated:YES]; ParsedResult *parsedResult = [[ResultParser parsedResultForString:resultString] retain]; NSArray *actions = [[parsedResult actions] retain]; if ([actions count] == 1) { ResultAction *theAction = [actions objectAtIndex:0]; [theAction performActionWithController:self shouldConfirm:YES]; } else { UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Text Found:" message:resultString delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alertView show]; [alertView release]; } }
The code in
viewWillAppear
is lifted off from the sample projects. This sets up the scanning video camera with the appropriate reader. If a scan is successful, the delegate method didScanResult
will execute. The result is parsed to see if it is a URL. You set which parser to use in viewDidLoad
. A parsed result can have default actions associated with it, the URLResultParser
opens up the url in Safari as default. Otherwise the result is treated as text and displayed.This app can now scan QR codes and open up URLs in Safari. There are a number of other things you can add to this, eg you can switch out the
ResultParser
with a UniversalResultParser
that includes all the parser classes. You should take a look in the Classes
folder of the ZXingWidget
project to see what is available.