I used ZXing to scan QR codes in iOS development. Here we will summarize how to integrate ZXing into an existing iOS project and share it with you.
Integration steps
First, go to Google Code or Github to download the ZXing Code. The whole project is large. We only need the part that involves iOS, so we 'd better make some cropping. Simply put, we only need to keep the cpp and iphone folders, and delete all the other folders. As shown in:
Next, we continue to crop the directory cpp. For the cpp directory, only the content under cpp/core/src/zxing is retained, and the rest of the content can be deleted. However, the entire directory structure must be unchanged. After cropping, the entire directory structure is as follows:
Next, we move the cropped zxing directory to the directory of our iOS project, and drag the ZXingWidget. xcodeproj file that we can see in to our iOS project.
Next, we need to set the dependency between the ZXing project and our original iOS project. In settings of our iOS project, click build phases tab, add Target Dependencies and Link binary, and add these framework Dependencies:
A. AVFoundation
B. AudioToolbox
C. CoreVideo
D. CoreMedia
E. libiconv
F. AddressBook
G. AddressBookUI
As shown in figure:
In the last step, add the following two header search paths in the settings:
./Zxing/iphone/ZXingWidget/Classes
./Zxing/cpp/core/src
Note that the first path needs to be set to a circular search subdirectory, while the second path does not, as shown in:
Congratulations, after completing this step, you have completed ZXing library integration. The following describes how to use the ZXing library for QR code recognition.
QR code recognition
The iOS version of ZXing provides two methods for QR code recognition. The first method is relatively simple, and the second method is relatively complicated. I used the first method in Demo and the second method in real project development, so I will introduce it to you.
Method 1
ZXing directly provides a View Controller that scans the QR code, that is, ZXingWidgetController. Add the file dependency to the interface code to be used:
1 # import <ZXingWidgetController. h>
2 # import <QRCodeReader. h>
Then, when scanning is required, call the following code:
1-(IBAction) scanPressed :( id) sender {
2 ZXingWidgetController * widController = [[ZXingWidgetController alloc] initWithDelegate: self showCancel: YES OneDMode: NO];
3 NSMutableSet * readers = [[NSMutableSet alloc] init];
4 QRCodeReader * qrcodeReader = [[QRCodeReader alloc] init];
5 [readers addObject: qrcodeReader];
6 [qrcodeReader release];
7 widController. readers = readers;
8 [readers release];
9 [self presentModalViewController: widController animated: YES];
10 [widController release];
11}
When a ZXing scan has a result, the following callback function is called:
1 @ protocol ZXingDelegate
2-(void) zxingController :( ZXingWidgetController *) controller didScanResult :( NSString *) result;
3-(void) zxingControllerDidCancel :( ZXingWidgetController *) controller;
4 @ end
Method 2
The difference between method 2 and method 1 is the same as that between AVFoundation and UIImagePickerController. In simple terms, it is more difficult to use method 2 than method 1, but it is more customizable.
When using method 2, you need to use AVFoundation to obtain the real-time image returned by Camera, convert it to a UIImage, and finally pass it to the Decoder class of ZXing for QR code recognition. The code I wrote is as follows:
1 # import "Decoder. h"
2 # import "TwoDDecoderResult. h"
3 # import "QRCodeReader. h"
4
5-(void) viewDidLoad {
6 // setup QR reader
7 self. qrReader = [[NSMutableSet alloc] init];
8 QRCodeReader * qrcodeReader = [[QRCodeReader alloc] init];
9 [self. qrReader addObject: qrcodeReader];
10 self. scanningQR = NO;
11 self. step = STEP_QR;
12}
13
14 // AVFoundation callback function
15-(void) captureOutput :( AVCaptureOutput *) captureOutput didOutputSampleBuffer :( CMSampleBufferRef) sampleBuffer fromConnection :( AVCaptureConnection *) connection {
16 // Step 1: Convert sampleBuffer to UIImage
17 UIImage * image = [self getCaptureImage: sampleBuffer];
18 // Step 2: Use Decoder to recognize images
19 Decoder * d = [[Decoder alloc] init];
20 d. readers = self. qrReader;
21 d. delegate = self;
22 self. scanningQR = [d decodeImage: image] = YES? NO: YES;
23}
ZXing's Decoder class provides the following callback functions for recognition:
1 @ protocol DecoderDelegate <NSObject>
2 @ optional
3-(void) decoder :( Decoder *) decoder willDecodeImage :( UIImage *) image usingSubset :( UIImage *) subset;
4-(void) decoder :( Decoder *) decoder didDecodeImage :( UIImage *) image usingSubset :( UIImage *) subset withResult :( TwoDDecoderResult *) result {
5 NSLog (@ "result = % @", [result text]);
6}
7-(void) decoder :( Decoder *) decoder failedToDecodeImage :( UIImage *) image usingSubset :( UIImage *) subset reason :( NSString *) reason;
8-(void) decoder :( Decoder *) decoder foundPossibleResultPoint :( CGPoint) point;
9
10 @ end
Trouble Shoot & Tips
I encountered some problems in use, mainly the compilation problem.
One is that the header file cannot be found. Solution: Change the source file extension used for ZXing from. m to. mm.
Error: Undefined symbols for architecture armv7s. Solution: change a build target parameter of ZXingWidget: "Build Active Architecture Only" to "NO ".
Error: No such file or directory. This error may be caused by an error in your Header Search Path, or the directory structure of your zxing library is not mentioned above, check it out.
ZXing and OpenCV compatibility
ZXing 2.1 has some compatibility issues with the iOS library of OpenCV 2.4.3. They have some requirements for the C ++ standard library version and the compiler version, thus meeting the requirements, the other party fails the compilation. Someone on Stackoverflow finally found a way to make them coexist, but it only applies to iOS5.0 and later versions. Our App only supports iOS5.0 +. So if you encounter this problem, you can refer to this post.