patternMinor
AVCaptureMetadataOutputObjects Wrapper
Viewed 0 times
wrapperavcapturemetadataoutputobjectsstackoverflow
Problem
With iOS7, Apple introduced
But I decided to make it even easier. I'm working on a wrapper class that will turn several lines of code into just a few lines.
NHGBarcodeScanner.h
NHGBarcodeScanner.m
```
#import "NHGBarcodeScanner.h"
@interface NHGBarcodeScanner()
@end
@implementation NHGBarcodeScanner {
AVCaptureSession *_captureSession;
NSArray *_barcodeTypes;
}
+ (instancetype)nhgBarcodeScannerWithFrame:(CGRect)frame
barcodeTypes:(BarcodeType)barcodeTypes
delegate:(id)delegate {
return [[self alloc] initWithFrame:frame barcodeTypes:barcodeTypes delegate:delegate];
}
barcodeTypes:(BarcodeType)barcodeTypes
AVCaptureMetadataOutputObjects, which is used for scanning barcodes. If you check out the web for how to scan barcodes in iOS, almost everyone is talking about ZBarSDK. And before iOS7, this was definitely the way to go. But as of iOS7, ZBarSDK has a pretty nasty memory leak, and it's a big library to include when you consider barcode scanning functionality is already built into iOS7. Moreover, I consider Apple's approach to be a slightly easier than ZBarSDK was anyway.But I decided to make it even easier. I'm working on a wrapper class that will turn several lines of code into just a few lines.
NHGBarcodeScanner.h
#import
#import
typedef NS_OPTIONS(unsigned short, BarcodeType) {
CODE_UPCE = 1
@required - (void)barcodeScannerDidScan:(NSString*)result;
@optional - (void)barcodeInitDidFailWithError:(NSError*)error;
@end
@interface NHGBarcodeScanner : UIView
@property (nonatomic,assign) id delegate;
- (id)init __attribute__((unavailable()));
- (id)initWithFrame:(CGRect)frame __attribute__((unavailable()));
- (id)initWithFrame:(CGRect)frame barcodeTypes:(BarcodeType)barcodeTypes
delegate:(id)delegate;
+ (instancetype)nhgBarcodeScannerWithFrame:(CGRect)frame
barcodeTypes:(BarcodeType)barcodeTypes
delegate:(id)delegate;
- (void)startScanning;
@endNHGBarcodeScanner.m
```
#import "NHGBarcodeScanner.h"
@interface NHGBarcodeScanner()
@end
@implementation NHGBarcodeScanner {
AVCaptureSession *_captureSession;
NSArray *_barcodeTypes;
}
+ (instancetype)nhgBarcodeScannerWithFrame:(CGRect)frame
barcodeTypes:(BarcodeType)barcodeTypes
delegate:(id)delegate {
return [[self alloc] initWithFrame:frame barcodeTypes:barcodeTypes delegate:delegate];
}
- (id)initWithFrame:(CGRect)frame
barcodeTypes:(BarcodeType)barcodeTypes
Solution
One possible improvement for the sake of convenience could be to add some meta groups to the enum.
For example:
Now instead of combining large groups with the
What's also potentially missing is a way to grab multiple codes in a batch.
There are two potential ways of sending the multiple codes.
For example:
typedef NS_OPTIONS(unsigned short, BarcodeType) {
CODE_UPCE = 1 << 0,
CODE_CODE39 = 1 << 1,
CODE_CODE39MOD43 = 1 << 2,
CODE_EAN13 = 1 << 3,
CODE_EAN8 = 1 << 4,
CODE_CODE93 = 1 << 5,
CODE_CODE128 = 1 << 6,
CODE_PDF417 = 1 << 7,
CODE_QRCODE = 1 << 8,
CODE_AZTEC = 1 << 9
}
typedef NS_OPTIONS(unsigned short, BarcodeGroup) {
CODEGROUP_1DBarcodes = 1 << 0
+ 1 << 1
+ 1 << 2
+ 1 << 3
+ 1 << 4
+ 1 << 5
+ 1 << 6
CODEGROUP_2DBarcodes = 1 << 7
+ 1 << 8
+ 1 << 9
CODEGROUP_ALLBarcodes = 1 << 0
+ 1 << 1
+ 1 << 2
+ 1 << 3
+ 1 << 4
+ 1 << 5
+ 1 << 6
+ 1 << 7
+ 1 << 8
+ 1 << 9
};Now instead of combining large groups with the
|, a user could instead simply call one of these code groups if they needed all, or just 1d codes or just 2d codes.What's also potentially missing is a way to grab multiple codes in a batch.
AVCaptureMetadataOutput will capture as many barcodes as you put in front of it all at once. It puts all these symbols into an array, and then your forin loops in the delegate method grab a single one of these codes.There are two potential ways of sending the multiple codes.
- The delegate method (
barcodeScannerDidScan:) could take anNSArrayargument, rather than a singleNSString. Internally,captureOutput:didOutputMetadataObjects:fromConnection:would then just need a singleforinloop to check that the symbol matches the requested symbols, and use this loop to build an array. After the array is built, send it to the delegate.
- The
return;can be removed from the nestedforinloops. The result is the delegate method will be called once for each barcode that was scanned.
Code Snippets
typedef NS_OPTIONS(unsigned short, BarcodeType) {
CODE_UPCE = 1 << 0,
CODE_CODE39 = 1 << 1,
CODE_CODE39MOD43 = 1 << 2,
CODE_EAN13 = 1 << 3,
CODE_EAN8 = 1 << 4,
CODE_CODE93 = 1 << 5,
CODE_CODE128 = 1 << 6,
CODE_PDF417 = 1 << 7,
CODE_QRCODE = 1 << 8,
CODE_AZTEC = 1 << 9
}
typedef NS_OPTIONS(unsigned short, BarcodeGroup) {
CODEGROUP_1DBarcodes = 1 << 0
+ 1 << 1
+ 1 << 2
+ 1 << 3
+ 1 << 4
+ 1 << 5
+ 1 << 6
CODEGROUP_2DBarcodes = 1 << 7
+ 1 << 8
+ 1 << 9
CODEGROUP_ALLBarcodes = 1 << 0
+ 1 << 1
+ 1 << 2
+ 1 << 3
+ 1 << 4
+ 1 << 5
+ 1 << 6
+ 1 << 7
+ 1 << 8
+ 1 << 9
};Context
StackExchange Code Review Q#42252, answer score: 4
Revisions (0)
No revisions yet.