diff --git a/ios/Classes/BarcodeScannerViewController.h b/ios/Classes/BarcodeScannerViewController.h new file mode 100644 index 0000000..6ee6a59 --- /dev/null +++ b/ios/Classes/BarcodeScannerViewController.h @@ -0,0 +1,16 @@ +// +// Created by Matthew Smith on 11/7/17. +// + +#import +#import + +#import "BarcodeScannerViewControllerDelegate.h" + + +@interface BarcodeScannerViewController : UIViewController +@property(nonatomic, retain) UIView *previewView; +@property(nonatomic, retain) MTBBarcodeScanner *scanner; +@property(nonatomic, weak) id delegate; + +@end \ No newline at end of file diff --git a/ios/Classes/BarcodeScannerViewController.m b/ios/Classes/BarcodeScannerViewController.m new file mode 100644 index 0000000..6dbdc4e --- /dev/null +++ b/ios/Classes/BarcodeScannerViewController.m @@ -0,0 +1,135 @@ +// +// Created by Matthew Smith on 11/7/17. +// + +#import "BarcodeScannerViewController.h" +#import + + +@implementation BarcodeScannerViewController { +} + + +- (void)viewDidLoad { + [super viewDidLoad]; + self.previewView = [[UIView alloc] initWithFrame:self.view.bounds]; + self.previewView.translatesAutoresizingMaskIntoConstraints = NO; + [self.view addSubview:_previewView]; + [self.view addConstraints:[NSLayoutConstraint + constraintsWithVisualFormat:@"V:[previewView]" + options:NSLayoutFormatAlignAllBottom + metrics:nil + views:@{@"previewView": _previewView}]]; + [self.view addConstraints:[NSLayoutConstraint + constraintsWithVisualFormat:@"H:[previewView]" + options:NSLayoutFormatAlignAllBottom + metrics:nil + views:@{@"previewView": _previewView}]]; + self.scanner = [[MTBBarcodeScanner alloc] initWithPreviewView:_previewView]; + self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel)]; +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + if (self.scanner.isScanning) { + [self.scanner stopScanning]; + } + [MTBBarcodeScanner requestCameraPermissionWithSuccess:^(BOOL success) { + if (success) { + [self startScan]; + } else { + [self showNoCameraAccessAlert]; + } + }]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + if ([self isFlashOn]) { + [self toggleFlash:NO]; + } +} + +- (void)startScan { + NSError *error; + [self.scanner startScanningWithResultBlock:^(NSArray *codes) { + [self.scanner stopScanning]; + AVMetadataMachineReadableCodeObject *code = codes.firstObject; + if (code) { + [self.delegate barcodeScannerViewController:self didScanBarcodeWithResult:code.stringValue]; + [self dismissViewControllerAnimated:NO completion:nil]; + } + } error:&error]; +} + +- (void)cancel { + [self dismissViewControllerAnimated:true completion:nil]; +} + +- (void)updateFlashButton { + if (!self.hasTorch) { + return; + } + if (self.isFlashOn) { + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Flash Off" + style:UIBarButtonItemStylePlain + target:self action:@selector(toggle)]; + } else { + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Flash On" + style:UIBarButtonItemStylePlain + target:self action:@selector(toggle)]; + } +} + +- (void)showNoCameraAccessAlert { + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Camera access denied" + message:@"Camera access has been disabled for this application. To turn camera access back on, please go to the iOS settings application." + preferredStyle:UIAlertControllerStyleAlert]; + [alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { + [self dismissViewControllerAnimated:YES completion:nil]; + }]]; + [self presentViewController:alertController animated:YES completion:nil]; +} + +- (void)toggle { + [self toggleFlash:!self.isFlashOn]; + [self updateFlashButton]; +} + +- (BOOL)isFlashOn { + AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; + if (device) { + return device.torchMode == AVCaptureFlashModeOn || AVCaptureTorchModeOn; + } + return NO; +} + +- (BOOL)hasTorch { + AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; + if (device) { + return device.hasTorch; + } + return false; +} + +- (void)toggleFlash:(BOOL)on { + AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; + if (!device) return; + + NSError *err; + if (device.hasFlash && device.hasTorch) { + [device lockForConfiguration:&err]; + if (err != nil) return; + if (on) { + device.flashMode = AVCaptureFlashModeOn; + device.torchMode = AVCaptureTorchModeOn; + } else { + device.flashMode = AVCaptureFlashModeOff; + device.torchMode = AVCaptureTorchModeOff; + } + [device unlockForConfiguration]; + } +} + + +@end \ No newline at end of file diff --git a/ios/Classes/BarcodeScannerViewControllerDelegate.h b/ios/Classes/BarcodeScannerViewControllerDelegate.h new file mode 100644 index 0000000..b5c0663 --- /dev/null +++ b/ios/Classes/BarcodeScannerViewControllerDelegate.h @@ -0,0 +1,13 @@ +// +// Created by Matthew Smith on 11/7/17. +// + +#import + +@class BarcodeScannerViewController; + +@protocol BarcodeScannerViewControllerDelegate + +- (void)barcodeScannerViewController:(BarcodeScannerViewController *)controller didScanBarcodeWithResult:(NSString *)result; + +@end \ No newline at end of file