diff --git a/Camera.ios.js b/Camera.ios.js
index c83869d..d959c1b 100644
--- a/Camera.ios.js
+++ b/Camera.ios.js
@@ -1,4 +1,5 @@
var React = require('React');
+var DeviceEventEmitter = require('RCTDeviceEventEmitter');
var NativeModules = require('NativeModules');
var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
var StyleSheet = require('StyleSheet');
@@ -37,6 +38,11 @@ var Camera = React.createClass({
this.state.isAuthorized = isAuthorized;
this.setState(this.state);
}).bind(this));
+ this.cameraBarCodeReadListener = DeviceEventEmitter.addListener('CameraBarCodeRead', this._onBarCodeRead);
+ },
+
+ componentWillUnmount: function() {
+ this.cameraBarCodeReadListener.remove();
},
render: function() {
@@ -50,12 +56,16 @@ var Camera = React.createClass({
style,
aspect: aspect,
type: type,
- orientation: orientation,
+ orientation: orientation
});
return
},
+ _onBarCodeRead(e) {
+ this.props.onBarCodeRead && this.props.onBarCodeRead(e);
+ },
+
switch: function() {
this.state.type = this.state.type == 'Back' ? 'Front' : 'Back';
this.setState(this.state);
diff --git a/RCTCameraManager.h b/RCTCameraManager.h
index 955692a..fb9dc13 100644
--- a/RCTCameraManager.h
+++ b/RCTCameraManager.h
@@ -3,12 +3,13 @@
@class RCTCamera;
-@interface RCTCameraManager : RCTViewManager
+@interface RCTCameraManager : RCTViewManager
@property (nonatomic) dispatch_queue_t sessionQueue;
@property (nonatomic) AVCaptureSession *session;
@property (nonatomic) AVCaptureDeviceInput *captureDeviceInput;
@property (nonatomic) AVCaptureStillImageOutput *stillImageOutput;
+@property (nonatomic) AVCaptureMetadataOutput *metadataOutput;
@property (nonatomic) id runtimeErrorHandlingObserver;
@property (nonatomic) NSInteger presetCamera;
@property (nonatomic) AVCaptureVideoPreviewLayer *previewLayer;
diff --git a/RCTCameraManager.m b/RCTCameraManager.m
index 1249e52..0b8e563 100644
--- a/RCTCameraManager.m
+++ b/RCTCameraManager.m
@@ -1,6 +1,7 @@
#import "RCTCameraManager.h"
#import "RCTCamera.h"
#import "RCTBridge.h"
+#import "RCTEventDispatcher.h"
#import "RCTUtils.h"
#import "RCTLog.h"
#import "UIView+React.h"
@@ -82,6 +83,14 @@ RCT_EXPORT_VIEW_PROPERTY(orientation, NSInteger);
self.stillImageOutput = stillImageOutput;
}
+ AVCaptureMetadataOutput *metadataOutput = [[AVCaptureMetadataOutput alloc] init];
+ if ([self.session canAddOutput:metadataOutput]) {
+ [metadataOutput setMetadataObjectsDelegate:self queue:self.sessionQueue];
+ [self.session addOutput:metadataOutput];
+ [metadataOutput setMetadataObjectTypes:metadataOutput.availableMetadataObjectTypes];
+ self.metadataOutput = metadataOutput;
+ }
+
__weak RCTCameraManager *weakSelf = self;
[self setRuntimeErrorHandlingObserver:[NSNotificationCenter.defaultCenter addObserverForName:AVCaptureSessionRuntimeErrorNotification object:self.session queue:nil usingBlock:^(NSNotification *note) {
RCTCameraManager *strongSelf = weakSelf;
@@ -168,6 +177,44 @@ RCT_EXPORT_METHOD(takePicture:(RCTResponseSenderBlock)callback) {
}];
}
+- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
+
+ NSArray *barcodeTypes = @[
+ AVMetadataObjectTypeUPCECode,
+ AVMetadataObjectTypeCode39Code,
+ AVMetadataObjectTypeCode39Mod43Code,
+ AVMetadataObjectTypeEAN13Code,
+ AVMetadataObjectTypeEAN8Code,
+ AVMetadataObjectTypeCode93Code,
+ AVMetadataObjectTypeCode128Code,
+ AVMetadataObjectTypePDF417Code,
+ AVMetadataObjectTypeQRCode,
+ AVMetadataObjectTypeAztecCode
+ ];
+
+ for (AVMetadataMachineReadableCodeObject *metadata in metadataObjects) {
+ for (id barcodeType in barcodeTypes) {
+ if (metadata.type == barcodeType) {
+
+ [self.bridge.eventDispatcher sendDeviceEventWithName:@"CameraBarCodeRead"
+ body:@{
+ @"data": metadata.stringValue,
+ @"bounds": @{
+ @"origin": @{
+ @"x": [NSString stringWithFormat:@"%f", metadata.bounds.origin.x],
+ @"y": [NSString stringWithFormat:@"%f", metadata.bounds.origin.y]
+ },
+ @"size": @{
+ @"height": [NSString stringWithFormat:@"%f", metadata.bounds.size.height],
+ @"width": [NSString stringWithFormat:@"%f", metadata.bounds.size.width],
+ }
+ }
+ }];
+ }
+ }
+ }
+}
+
- (AVCaptureDevice *)deviceWithMediaType:(NSString *)mediaType preferringPosition:(AVCaptureDevicePosition)position
{
diff --git a/README.md b/README.md
index d39f372..31cff40 100644
--- a/README.md
+++ b/README.md
@@ -81,6 +81,11 @@ The `orientation` property allows you to specify the current orientation of the
TODO: Add support for an `Auto` value to automatically adjust for orientation changes.
+#### `onBarCodeRead`
+
+Will call the specified method when a barcode is detected in the camera's view.
+
+Event contains `data` (the data in the barcode) and `bounds` (the rectangle which outlines the barcode.)
## Component methods
diff --git a/package.json b/package.json
index c5ad7cc..52edfe3 100644
--- a/package.json
+++ b/package.json
@@ -4,8 +4,8 @@
"type" : "git",
"url" : "https://github.com/lwansbrough/react-native-camera.git"
},
- "version": "0.0.10",
- "description": "A Camera element for React Native",
+ "version": "0.1.0",
+ "description": "A Camera component for React Native. Also reads barcodes.",
"main": "Camera.ios.js",
"author": "Lochlan Wansbrough (http://lwansbrough.com)",
"dependencies": {
@@ -15,6 +15,9 @@
"react-native",
"react",
"native",
- "camera"
+ "camera",
+ "qr",
+ "code",
+ "barcode"
]
}