diff --git a/Classes/ios/Scanners/MTBBarcodeScanner.h b/Classes/ios/Scanners/MTBBarcodeScanner.h index 616802e..55daab9 100644 --- a/Classes/ios/Scanners/MTBBarcodeScanner.h +++ b/Classes/ios/Scanners/MTBBarcodeScanner.h @@ -300,6 +300,17 @@ typedef NS_ENUM(NSUInteger, MTBTorchMode) { */ - (BOOL)setTorchMode:(MTBTorchMode)torchMode error:(NSError **)error; +/** + * Attempts to set a new torch level. + * + * @return YES, if setting the new level was successful, and the torchMode + * property reflects the new state. NO if there was an error - use the + * error parameter to learn about the reason. + * + * @sa torchMode + */ +- (BOOL)setTorchLevel:(float)torchLevel error:(NSError **)error; + /** * Freeze capture keeping the last frame on previewView. * If this method is called before startScanning, it has no effect. diff --git a/Classes/ios/Scanners/MTBBarcodeScanner.m b/Classes/ios/Scanners/MTBBarcodeScanner.m index 8885b2c..38ac8a0 100644 --- a/Classes/ios/Scanners/MTBBarcodeScanner.m +++ b/Classes/ios/Scanners/MTBBarcodeScanner.m @@ -449,6 +449,7 @@ - (void)stopRecognizingTaps { - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection { if (!self.resultBlock) return; + if (self.isCapturingStillImage) return; NSMutableArray *codes = [[NSMutableArray alloc] init]; @@ -464,12 +465,21 @@ - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects: #pragma mark - Rotation -- (void)handleApplicationDidChangeStatusBarNotification:(NSNotification *)notification { +- (void)handleOrientationChangeNotification:(NSNotification *)notification { [self refreshVideoOrientation]; } - (void)refreshVideoOrientation { - UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; + UIInterfaceOrientation orientation; + if (@available(iOS 13.0, *)) { + orientation = self.previewView.window.windowScene.interfaceOrientation; + } else { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + orientation = [UIApplication sharedApplication].statusBarOrientation; +#pragma GCC diagnostic pop + } + self.capturePreviewLayer.frame = self.previewView.bounds; if ([self.capturePreviewLayer.connection isVideoOrientationSupported]) { self.capturePreviewLayer.connection.videoOrientation = [self captureOrientationForInterfaceOrientation:orientation]; @@ -644,8 +654,8 @@ + (AVCaptureDevicePosition)devicePositionForCamera:(MTBCamera)camera { - (void)addObservers { [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(handleApplicationDidChangeStatusBarNotification:) - name:UIApplicationDidChangeStatusBarOrientationNotification + selector:@selector(handleOrientationChangeNotification:) + name:UIDeviceOrientationDidChangeNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self @@ -747,6 +757,16 @@ - (BOOL)setTorchMode:(MTBTorchMode)torchMode error:(NSError **)error { return NO; } +- (BOOL)setTorchLevel:(float)torchLevel error:(NSError **)error { + if ([self updateForTorchLevel:torchLevel error:error]) { + // we only update our internal state if setting the torch mode was successful + _torchMode = MTBTorchModeOn; + return YES; + } + + return NO; +} + - (void)toggleTorch { switch (self.torchMode) { case MTBTorchModeOn: @@ -784,6 +804,30 @@ - (BOOL)updateForTorchMode:(MTBTorchMode)preferredTorchMode error:(NSError **)er return YES; } +- (BOOL)updateForTorchLevel:(float)preferredTorchLevel error:(NSError **)error { + AVCaptureDevice *backCamera = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; + + if (!([backCamera isTorchAvailable] && [backCamera isTorchModeSupported:AVCaptureTorchModeOn])) { + if (error) { + *error = [NSError errorWithDomain:kErrorDomain + code:kErrorCodeTorchModeUnavailable + userInfo:@{NSLocalizedDescriptionKey : @"Torch unavailable or mode not supported."}]; + } + + return NO; + } + + if (![backCamera lockForConfiguration:error]) { + NSLog(@"Failed to acquire lock to update torch mode."); + return NO; + } + + BOOL result = [backCamera setTorchModeOnWithLevel:preferredTorchLevel error:error]; + [backCamera unlockForConfiguration]; + + return result; +} + - (BOOL)hasTorch { AVCaptureDevice *captureDevice = [self newCaptureDeviceWithCamera:self.camera]; NSError *error = nil; @@ -846,20 +890,24 @@ - (void)captureStillImage:(void (^)(UIImage *image, NSError *error))captureBlock return; } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" if (@available(iOS 10.0, *)) { AVCapturePhotoSettings *settings = [AVCapturePhotoSettings photoSettings]; - settings.autoStillImageStabilizationEnabled = NO; settings.flashMode = AVCaptureFlashModeOff; settings.highResolutionPhotoEnabled = YES; - + + if (@available(iOS 13.0, *)) { + settings.photoQualityPrioritization = AVCapturePhotoQualityPrioritizationSpeed; + } else { + settings.autoStillImageStabilizationEnabled = NO; + } + dispatch_async(self.privateSessionQueue, ^{ [self.output capturePhotoWithSettings:settings delegate:self]; self.stillImageCaptureBlock = captureBlock; - }); } else { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" AVCaptureConnection *stillConnection = [self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo]; if (stillConnection == nil) { if (captureBlock) { @@ -884,8 +932,9 @@ - (void)captureStillImage:(void (^)(UIImage *image, NSError *error))captureBlock captureBlock(image, nil); } }]; -#pragma GCC diagnostic pop } +#pragma GCC diagnostic pop + } #pragma mark - AVCapturePhotoCaptureDelegate diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..7156446 --- /dev/null +++ b/Package.swift @@ -0,0 +1,20 @@ +// swift-tools-version:5.3 +import PackageDescription + +let package = Package( + name: "MTBBarcodeScanner", + platforms: [.iOS(.v9)], + products: [ + .library( + name: "MTBBarcodeScanner", + targets: ["MTBBarcodeScanner"] + ) + ], + targets: [ + .target( + name: "MTBBarcodeScanner", + path: "Classes/ios", + publicHeadersPath: "." + ) + ] +) diff --git a/Project/MTBBarcodeScanner/Info.plist b/Project/MTBBarcodeScanner/Info.plist index 7e7479f..8d8e3b4 100644 --- a/Project/MTBBarcodeScanner/Info.plist +++ b/Project/MTBBarcodeScanner/Info.plist @@ -22,5 +22,7 @@ $(CURRENT_PROJECT_VERSION) NSPrincipalClass + NSCameraUsageDescription + For testing purposes diff --git a/Project/MTBBarcodeScannerExample/Classes/Controllers/SwiftExampleViewController.swift b/Project/MTBBarcodeScannerExample/Classes/Controllers/SwiftExampleViewController.swift index 515818e..8d3f09e 100644 --- a/Project/MTBBarcodeScannerExample/Classes/Controllers/SwiftExampleViewController.swift +++ b/Project/MTBBarcodeScannerExample/Classes/Controllers/SwiftExampleViewController.swift @@ -17,7 +17,11 @@ class SwiftExampleViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() + // Scan all types of codes scanner = MTBBarcodeScanner(previewView: previewView) + + // If you want to scan only QR codes, use this instead! +// scanner = MTBBarcodeScanner(metadataObjectTypes: [AVMetadataObject.ObjectType.qr.rawValue], previewView: previewView) } override func viewDidAppear(_ animated: Bool) { diff --git a/README.md b/README.md index 0d5ae5b..4fde24b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +# This library is no longer actively maintained. If you are interested in maintaining it, please contact [the original author](mailto:mike@mikebuss.com). + # MTBBarcodeScanner [![Version](https://img.shields.io/cocoapods/v/MTBBarcodeScanner.svg?style=flat)](http://cocoadocs.org/docsets/MTBBarcodeScanner) @@ -200,6 +202,9 @@ class SwiftExampleViewController: UIViewController { super.viewDidLoad() scanner = MTBBarcodeScanner(previewView: previewView) + + // Alternatively, limit the type of codes you can scan: + // scanner = MTBBarcodeScanner(metadataObjectTypes: [AVMetadataObject.ObjectType.qr.rawValue], previewView: previewView) } override func viewDidAppear(_ animated: Bool) {