Scan and recognize QR codes from your iOS application

QR codes today are used almost everywhere you can imagine. It is quite obvious that many developers would be interested in learning how to organize scanning and recognition of QR codes in their applications for mobile devices.

In the process of developing my own iOS application, I was faced with the fact that there is very little information in Russian on the topic of processing QR codes on the Internet. Having dealt with the application itself, I decided that it was necessary to rectify this flagrantly unfair situation. Under the cut you will find a description of the development process of an extremely simple application that recognizes QR codes and is of interest to beginner iOS developers. This note assumes a basic knowledge of the features of working in Xcode and programming for iOS.

Development will be conducted forXcode 4.1 , for earlier versions of Xcode (starting with version 3.2.3 ) the process will be almost the same.
The task of scanning and pattern recognition, generally speaking, is quite complicated from the point of view of mathematical and technical implementation. In other words, it’s quite difficult to develop an application that recognizes a barcode or QR code from scratch. Fortunately for us, progress does not stand still, and most of the complicated work of scanning and recognition has already been decided by someone. Which we will use.
So, for work you will need:
  • Mac OS X> = 10.6.x (Snow Leopard) , I have 10.7.2 Lion, respectively.
  • Xcode> = 3.2.3 , I worked in version 4.1.
  • iPhone> = 3GS , I tested on iPhone 3GS and iPad 2.
  • iOS 4.0 and higher on the device (in fact, 3.1 is also possible).
  • IOS Developer account-record , because without it, you cannot test developed applications on physical devices.

Since the iOS device emulator distributed with Xcode cannot emulate the camera, to test the application we need a real device - iPhone , iPod Touch or iPad 2 , i.e. any device with a camera released over the past 2 years is quite suitable for itself.

Also for work, we will use the SDK for scanning and recognizing QR codes, which will take care of processing the graphic image of the QR code and converting it into text information. There are several ready-made open-source libraries that offer similar functionality, we will use the ZBar iPhone SDK SDK version 1.2 (version above 1.2 is also suitable), which can be downloaded here .

Using the specified link, you will download the ZBarSDK-1.2.dmg image , inside which we will be interested in the ZBarSDK folder , which contains the library we need.

So let's get started.

1. Launch Xcode, create a new “View-based Application” project in it , call it QR Scanner , and save it somewhere in a place convenient for you on the disk.

2. In the Project navigator, open QR_ScannerViewController.xib .

3. Place on the Round Rect Button form and place on it, for example, the text “Scan QR code” .

4. Place the Image View element at the top of the form, set the view mode property in Aspect Fit in the Object Inspector.

5. Place the Text View element in the lower part of the form , remove the stub text, and instead place, for example, the text "To start scanning a QR code, click on the button at the bottom of the screen . " Uncheck the User Interaction Enabled checkbox in the Object Inspector.

6. Add outlets to the controller code. To do this, open QR_ScannerViewController.h and bring it to this form:
#import 
@interface QR_ScannerViewController : UIViewController {
    UITextView *resultText;
    UIImageView *resultImage;
}
@property (nonatomic, retain) IBOutlet UIImageView *resultImage;
@property (nonatomic, retain) IBOutlet UITextView *resultText;
- (IBAction)scanButtonTapped;
@end


As you can see from the code, we announced two outlets for the UITextView and UIImageView controls that we placed on our form. In addition, we announced IBAction, which will process the click of our button and scan the QR code.

7. Open QR_ScannerViewController.xib and associate the outlets we created and the scanButtonTapped action with the corresponding form elements:
  • We connect the resultImage outlet with the ImageView element.
  • We connect the resultText outlet with the TextView element.
  • We associate the scanButtonTapped action with the TouchUpInside event of the Round Rect Button.

8. Now we need to create an implementation of the objects declared in the header file of the QR_ScannerViewController class . Open the file QR_ScannerViewController.m and bring it to the following form:
#import "QR_ScannerViewController.h"
@implementation QR_ScannerViewController
@synthesize resultImage;
@synthesize resultText;
- (IBAction)scanButtonTapped{
    NSLog(@"Now we are scanning QR-code...");
}
- (void)didReceiveMemoryWarning
{    [super didReceiveMemoryWarning];}
- (void)viewDidUnload
{
    [super viewDidUnload];
    self.resultText = nil;
    self.resultImage = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{ return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);}
- (void) dealloc {
    [resultImage release];
    [resultText release];
    [super dealloc];
}

If you are not too familiar with application development in Xcode, do not be alarmed - the development environment has added most of the code to this file itself. We just implemented the objects and actions declared in the header file:
@synthesize resultImage;
@synthesize resultText;
- (IBAction)scanButtonTapped{
    NSLog(@"Now we are scanning QR-code...");
}

In addition, we added code to free the outlets when the form is unloaded from memory (viewDidUnload):
self.resultText = nil;
self.resultImage = nil;

We also free up memory in dealloc:
[resultImage release];
[resultText release];


9. Now we need to directly include the previously downloaded ZBarSDK library in our application . To do this, open the ZBarSDK-1.2.dmg disk image , find the ZBarSDK folder in it and drag it from Finder into your project in Xcode.

10. Next, we need to add several additional libraries to our project. In the Target properties of our project, open the Build Phases tab , open the Link Binary With Libraries drop-down list and click on the plus sign in the lower left part of this list to add the following libraries:
  • AVFoundation.framework
  • Coremedia.framework
  • CoreVideo.framework
  • QuartzCore.framework
  • libiconv.dylib

11. Import the header file of our SDK. To do this, open the file “QR Scanner-Prefix.pch” and add the line to it:
 #import "ZBarSDK.h" 


12. For our controller class QR_ScannerViewController, declare delegate protocol support, for this, in the file QR_ScannerViewController.h we will correct the class declaration:
@interface QR_ScannerViewController : UIViewController {
    UITextView *resultText;
    UIImageView *resultImage;
}


13. Now we are fully prepared to make the application begin to do something useful. In the file QR_ScannerViewController.m, change the scanButtonTapped code to the following:
- (IBAction)scanButtonTapped{
    // Создаем объект, получающий картинку с камеры
    ZBarReaderViewController *reader = [ZBarReaderViewController new];
    reader.readerDelegate = self;
    reader.supportedOrientationsMask = ZBarOrientationMaskAll;
    ZBarImageScanner *scanner = reader.scanner;
/* 
Мы будем считывать только QR-коды. Для этого мы сперва отключим распознавание всех поддерживаемых библиотекой штрих-кодов…
*/
    [scanner setSymbology:0 config:ZBAR_CFG_ENABLE to:0];
/*
… а затем включим распознавание QR-кодов:
*/
    [scanner setSymbology:ZBAR_QRCODE config:ZBAR_CFG_ENABLE to:1];
    reader.readerView.zoom = 1.0;
/*
Далее показываем пользователю в модальном режиме представление (форму), сканирующую QR-код:
*/
    [self presentModalViewController:reader animated:YES];
    [reader release];
}

Now after clicking on the button in the application, this method will be called, which will directly call the view on which the picture from the camera will be displayed. It will be enough for the user to point the camera at the QR code, after which he will be read and processed.

14. However, it is not enough to read and process the QR code; it is also necessary to show the user the processing results. To do this, we need to implement the following delegate method (all in the same QR_ScannerViewController.m ):
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
/*
В результате распознавания  в info в общем случае возвращается что-то «перечисляемое»:
*/
    id results = [info objectForKey:ZBarReaderControllerResults];
/*
Опять же в общем случае результатов может быть несколько, следующий код всего лишь берет первый считанный и распознанный QR-код:
*/
ZBarSymbol *symbol = nil;
    for(symbol in results)
        // Считываем первый полученный результат
        break;
/*
Результат считывания и распознавания заносим в текстовое поле на форме через аутлет resultText:
*/ 
    resultText.text = symbol.data;
/*
Исходную картинку с QR-кодом заносим в объект UIImageView через аутлет resultImage:
*/
    resultImage.image =
    [info objectForKey: UIImagePickerControllerOriginalImage];
    // Прячем форму, с помощью которой фотографировали QR-код
    [picker dismissModalViewControllerAnimated:YES];
}

After this method works, the view that photographed the QR code will be removed from the screen and the original view developed by us in the file QR_ScannerViewController.xib will be shown . At this presentation, you will see a photo of the QR code and the text of this QR code.

15. That's all! Next, save the project, compile, run on the device.

16. To scan a QR code, click on the “Scan QR code” button and point the camera at the QR code image. The program will automatically “recognize” the QR code, take a picture of it and recognize it, after which it will display the information contained in it.

We left the description of the process of launching applications on the device behind the scenes, because, firstly, it is a rather long process from the point of view of description, and secondly, this article assumes that the reader has some information base regarding working with Xcode, which implicitly implies the ability to run developed applications on a physical device. Nevertheless, if readers have a desire, I can describe the process of organizing the launch of developed applications on a physical device in a separate note.

I also note that the library we used allows us to recognize not only QR codes, but also many other types of two-dimensional codes. We deliberately excluded this functionality from consideration in order to concentrate on the task of recognizing QR codes, as well as to stimulate independent study of this library by those whom it will interest.

In conclusion, some useful links on the topic of this article:
1. Site of developers of the ZBarSDK library .
2. Wikipedia about QR codes

Also popular now: