diff --git a/Sources/GiniCaptureSDK/Core/Screens/Camera/Camera/CameraViewController.swift b/Sources/GiniCaptureSDK/Core/Screens/Camera/Camera/CameraViewController.swift index ca0bea9..cd3fa9e 100644 --- a/Sources/GiniCaptureSDK/Core/Screens/Camera/Camera/CameraViewController.swift +++ b/Sources/GiniCaptureSDK/Core/Screens/Camera/Camera/CameraViewController.swift @@ -1,5 +1,5 @@ // -// Camera2ViewController.swift +// CameraViewController.swift // // // Created by Krzysztof Kryniecki on 06/09/2022. @@ -10,54 +10,54 @@ import AVFoundation import UIKit // swiftlint:disable type_body_length - final class CameraViewController: UIViewController, CameraScreen { +final class CameraViewController: UIViewController { /** The object that acts as the delegate of the camera view controller. - */ - let giniConfiguration: GiniConfiguration - var detectedQRCodeDocument: GiniQRCodeDocument? - - lazy var cameraPreviewViewController: CameraPreviewViewController = { - let cameraPreviewViewController = CameraPreviewViewController() - cameraPreviewViewController.delegate = self - return cameraPreviewViewController - }() - - private lazy var qrCodeOverLay: QRCodeOverlay = { - let view = QRCodeOverlay() - view.isHidden = true - view.translatesAutoresizingMaskIntoConstraints = false - return view - }() - - private lazy var ibanDetectionOverLay: IBANDetectionOverlay = { - let view = IBANDetectionOverlay() - view.isHidden = true - view.translatesAutoresizingMaskIntoConstraints = false - return view - }() - - private var resetQRCodeTask: DispatchWorkItem? - private var hideQRCodeTask: DispatchWorkItem? - private var validQRCodeProcessing: Bool = false - - private var isValidIBANDetected: Bool = false - - public weak var delegate: CameraViewControllerDelegate? - - private lazy var qrCodeScanningOnlyEnabled: Bool = { - return giniConfiguration.qrCodeScanningEnabled && giniConfiguration.onlyQRCodeScanningEnabled - }() - - @IBOutlet weak var cameraPane: CameraPane! - private let cameraButtonsViewModel: CameraButtonsViewModel - private var navigationBarBottomAdapter: CameraBottomNavigationBarAdapter? - private var bottomNavigationBar: UIView? - private let cameraLensSwitcherView: CameraLensSwitcherView - - @IBOutlet weak var iPadBottomPaneConstraint: NSLayoutConstraint! - @IBOutlet weak var bottomButtonsConstraints: NSLayoutConstraint! - @IBOutlet weak var bottomPaneConstraint: NSLayoutConstraint! + */ + let giniConfiguration: GiniConfiguration + var detectedQRCodeDocument: GiniQRCodeDocument? + + lazy var cameraPreviewViewController: CameraPreviewViewController = { + let cameraPreviewViewController = CameraPreviewViewController() + cameraPreviewViewController.delegate = self + return cameraPreviewViewController + }() + + private lazy var qrCodeOverLay: QRCodeOverlay = { + let view = QRCodeOverlay() + view.isHidden = true + view.translatesAutoresizingMaskIntoConstraints = false + return view + }() + + private lazy var ibanDetectionOverLay: IBANDetectionOverlay = { + let view = IBANDetectionOverlay() + view.isHidden = true + view.translatesAutoresizingMaskIntoConstraints = false + return view + }() + + private var resetQRCodeTask: DispatchWorkItem? + private var hideQRCodeTask: DispatchWorkItem? + private var validQRCodeProcessing: Bool = false + + private var isValidIBANDetected: Bool = false + + weak var delegate: CameraViewControllerDelegate? + + private lazy var qrCodeScanningOnlyEnabled: Bool = { + return giniConfiguration.qrCodeScanningEnabled && giniConfiguration.onlyQRCodeScanningEnabled + }() + + @IBOutlet weak var cameraPane: CameraPane! + private let cameraButtonsViewModel: CameraButtonsViewModel + private var navigationBarBottomAdapter: CameraBottomNavigationBarAdapter? + private var bottomNavigationBar: UIView? + private let cameraLensSwitcherView: CameraLensSwitcherView + + @IBOutlet weak var iPadBottomPaneConstraint: NSLayoutConstraint! + @IBOutlet weak var bottomButtonsConstraints: NSLayoutConstraint! + @IBOutlet weak var bottomPaneConstraint: NSLayoutConstraint! /** Designated initializer for the `CameraViewController` which allows to set the `GiniConfiguration for the camera screen`. @@ -67,8 +67,8 @@ import UIKit - returns: A view controller instance allowing the user to take a picture or pick a document. */ - public init(giniConfiguration: GiniConfiguration, - viewModel: CameraButtonsViewModel) { + public init(giniConfiguration: GiniConfiguration, + viewModel: CameraButtonsViewModel) { self.giniConfiguration = giniConfiguration self.cameraButtonsViewModel = viewModel @@ -89,21 +89,21 @@ import UIKit fatalError("init(coder:) has not been implemented") } - public override func viewDidLoad() { + override func viewDidLoad() { super.viewDidLoad() setupView() } - public override var preferredStatusBarStyle: UIStatusBarStyle { + override var preferredStatusBarStyle: UIStatusBarStyle { return giniConfiguration.statusBarStyle } - public override func viewWillAppear(_ animated: Bool) { + override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) cameraPane.toggleCaptureButtonActivation(state: true) } - public override func viewDidAppear(_ animated: Bool) { + override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) validQRCodeProcessing = false delegate?.cameraDidAppear(self) @@ -170,13 +170,13 @@ import UIKit var discoverySession: AVCaptureDevice.DiscoverySession if #available(iOS 13.0, *) { discoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInUltraWideCamera, - .builtInWideAngleCamera, - .builtInTelephotoCamera], - mediaType: .video, position: .back) + .builtInWideAngleCamera, + .builtInTelephotoCamera], + mediaType: .video, position: .back) } else { discoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera, - .builtInTelephotoCamera], - mediaType: .video, position: .back) + .builtInTelephotoCamera], + mediaType: .video, position: .back) } var availableLenses: [CameraLensesAvailable] = [] @@ -292,9 +292,9 @@ import UIKit if let imageData = data, let image = UIImage(data: imageData)?.fixOrientation() { let croppedImage = self.crop(image: image) processedImageData = croppedImage.jpegData(compressionQuality: 1) - #if targetEnvironment(simulator) +#if targetEnvironment(simulator) processedImageData = imageData - #endif +#endif } if let image = self.cameraButtonsViewModel.didCapture(imageData: data, @@ -377,7 +377,7 @@ import UIKit } private lazy var cameraPreviewBottomContraint: NSLayoutConstraint = - cameraPreviewViewController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor) + cameraPreviewViewController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor) private func configureConstraints() { if qrCodeScanningOnlyEnabled { @@ -388,7 +388,7 @@ import UIKit on: cameraPreviewViewController) } - ibanDetectionOverLay.layoutViews(centeringBy: cameraPreviewViewController.cameraFrameView, + ibanDetectionOverLay.layoutViews(centeringBy: cameraPreviewViewController.cameraFrameView, on: cameraPreviewViewController) NSLayoutConstraint.activate([ @@ -435,7 +435,7 @@ import UIKit delegate?.camera(self, didCapture: document) } - override public func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) coordinator.animate(alongsideTransition: nil) } @@ -445,13 +445,13 @@ import UIKit - parameter images: New images to be shown in the stack. (Last image will be shown on top) */ - public func replaceCapturedStackImages(with images: [UIImage]) { + func replaceCapturedStackImages(with images: [UIImage]) { if giniConfiguration.multipageEnabled { cameraButtonsViewModel.images = images } } - public func addValidationLoadingView() -> UIView { + func addValidationLoadingView() -> UIView { let loadingIndicator = UIActivityIndicatorView() loadingIndicator.applyLargeStyle() let blurredView = UIVisualEffectView(effect: UIBlurEffect(style: .dark)) @@ -468,47 +468,47 @@ import UIKit return blurredView } - // MARK: - IBANs Detection - private func showIBANFeedback(_ IBANs: [String]) { - isValidIBANDetected = !IBANs.isEmpty - guard isValidIBANDetected else { - hideIBANOverlay() - return + // MARK: - IBANs Detection + private func showIBANFeedback(_ IBANs: [String]) { + isValidIBANDetected = !IBANs.isEmpty + guard isValidIBANDetected else { + hideIBANOverlay() + return + } + + if !validQRCodeProcessing { + if !qrCodeOverLay.isHidden { + resetQRCodeScanning(isValid: false) + } + showIBANOverlay(with: IBANs) + } + } + + private func showIBANOverlay(with IBANs: [String]) { + + UIView.animate(withDuration: 0.3) { + self.ibanDetectionOverLay.isHidden = false + self.cameraPreviewViewController.changeCameraFrameColor(to: .GiniCapture.success2) + } + + ibanDetectionOverLay.configureOverlay(hidden: false) + ibanDetectionOverLay.setupView(with: IBANs) + } + + private func hideIBANOverlay() { + guard !ibanDetectionOverLay.isHidden else { return } + UIView.animate(withDuration: 0.3) { + self.ibanDetectionOverLay.isHidden = true + if self.qrCodeOverLay.isHidden { + self.cameraPreviewViewController.changeCameraFrameColor(to: .GiniCapture.light1) + } } + ibanDetectionOverLay.configureOverlay(hidden: true) + } + + // MARK: - QR Detection - if !validQRCodeProcessing { - if !qrCodeOverLay.isHidden { - resetQRCodeScanning(isValid: false) - } - showIBANOverlay(with: IBANs) - } - } - - private func showIBANOverlay(with IBANs: [String]) { - - UIView.animate(withDuration: 0.3) { - self.ibanDetectionOverLay.isHidden = false - self.cameraPreviewViewController.changeCameraFrameColor(to: .GiniCapture.success2) - } - - ibanDetectionOverLay.configureOverlay(hidden: false) - ibanDetectionOverLay.setupView(with: IBANs) - } - - private func hideIBANOverlay() { - guard !ibanDetectionOverLay.isHidden else { return } - UIView.animate(withDuration: 0.3) { - self.ibanDetectionOverLay.isHidden = true - if self.qrCodeOverLay.isHidden { - self.cameraPreviewViewController.changeCameraFrameColor(to: .GiniCapture.light1) - } - } - ibanDetectionOverLay.configureOverlay(hidden: true) - } - - // MARK: - QR Detection - - private func showQRCodeFeedback(for document: GiniQRCodeDocument, isValid: Bool) { + private func showQRCodeFeedback(for document: GiniQRCodeDocument, isValid: Bool) { guard !validQRCodeProcessing else { return } guard detectedQRCodeDocument != document else { return } @@ -633,14 +633,14 @@ extension CameraViewController: CameraLensSwitcherViewDelegate { var device: AVCaptureDevice? switch lens { - case .ultraWide: - if #available(iOS 13.0, *) { - device = AVCaptureDevice.default(.builtInUltraWideCamera, for: .video, position: .back) - } - case .wide: - device = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) - case .tele: - device = AVCaptureDevice.default(.builtInTelephotoCamera, for: .video, position: .back) + case .ultraWide: + if #available(iOS 13.0, *) { + device = AVCaptureDevice.default(.builtInUltraWideCamera, for: .video, position: .back) + } + case .wide: + device = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) + case .tele: + device = AVCaptureDevice.default(.builtInTelephotoCamera, for: .video, position: .back) } guard let device = device else { return } diff --git a/Sources/GiniCaptureSDK/Core/Screens/Camera/Protocols/CameraScreen.swift b/Sources/GiniCaptureSDK/Core/Screens/Camera/Protocols/CameraScreen.swift deleted file mode 100644 index aaaa2c7..0000000 --- a/Sources/GiniCaptureSDK/Core/Screens/Camera/Protocols/CameraScreen.swift +++ /dev/null @@ -1,23 +0,0 @@ -// -// CameraScreen.swift -// -// -// Created by Krzysztof Kryniecki on 12/09/2022. -// Copyright © 2022 Gini GmbH. All rights reserved. -// - -import AVFoundation -import Foundation -import UIKit - -@objc public protocol CameraScreen: CameraTips where Self: UIViewController { - weak var delegate: CameraViewControllerDelegate? {get set} - func setupCamera() - func addValidationLoadingView() -> UIView - func replaceCapturedStackImages(with images: [UIImage]) -} - -@objc public protocol CameraTips { - func hideCaptureButton() - func showCaptureButton() -} diff --git a/Sources/GiniCaptureSDK/Core/Screens/Camera/Protocols/CameraViewControllerDelegate.swift b/Sources/GiniCaptureSDK/Core/Screens/Camera/Protocols/CameraViewControllerDelegate.swift index 9cd398c..64b45ad 100644 --- a/Sources/GiniCaptureSDK/Core/Screens/Camera/Protocols/CameraViewControllerDelegate.swift +++ b/Sources/GiniCaptureSDK/Core/Screens/Camera/Protocols/CameraViewControllerDelegate.swift @@ -13,7 +13,7 @@ import UIKit The CameraViewControllerDelegate protocol defines methods that allow you to handle captured images and user actions. */ -@objc public protocol CameraViewControllerDelegate: AnyObject { + protocol CameraViewControllerDelegate: AnyObject { /** Called when a user takes a picture, imports a PDF/QRCode or imports one or several images. Once the method has been implemented, it is necessary to check if the number of @@ -23,8 +23,8 @@ import UIKit - parameter document: One or several documents either captured or imported in the `CameraViewController`. They can contain an error produced in the validation process. */ - @objc func camera(_ viewController: CameraScreen, - didCapture document: GiniCaptureDocument) + func camera(_ viewController: CameraViewController, + didCapture document: GiniCaptureDocument) /** Called when a user selects a picker from the picker selector sheet. @@ -32,14 +32,14 @@ import UIKit - parameter viewController: `CameraViewController` where the documents were taken. - parameter documentPicker: `DocumentPickerType` selected in the sheet. */ - @objc func camera(_ viewController: CameraScreen, didSelect documentPicker: DocumentPickerType) + func camera(_ viewController: CameraViewController, didSelect documentPicker: DocumentPickerType) /** Called when the `CameraViewController` appears. - parameter viewController: Camera view controller that appears. */ - @objc func cameraDidAppear(_ viewController: CameraScreen) + func cameraDidAppear(_ viewController: CameraViewController) /** Called when a user taps the `MultipageReviewButton` (the one with the thumbnail of the images(s) taken). @@ -47,6 +47,5 @@ import UIKit - parameter viewController: Camera view controller where the button was tapped. */ - @objc func cameraDidTapReviewButton(_ viewController: CameraScreen) - + func cameraDidTapReviewButton(_ viewController: CameraViewController) } diff --git a/Sources/GiniCaptureSDK/Core/Screens/Screen API Coordinator/GiniScreenAPICoordinator+Camera.swift b/Sources/GiniCaptureSDK/Core/Screens/Screen API Coordinator/GiniScreenAPICoordinator+Camera.swift index a44ebde..d31bc5b 100644 --- a/Sources/GiniCaptureSDK/Core/Screens/Screen API Coordinator/GiniScreenAPICoordinator+Camera.swift +++ b/Sources/GiniCaptureSDK/Core/Screens/Screen API Coordinator/GiniScreenAPICoordinator+Camera.swift @@ -19,7 +19,7 @@ import GiniBankAPILibrary extension GiniScreenAPICoordinator: CameraViewControllerDelegate { - public func camera(_ viewController: CameraScreen, didCapture document: GiniCaptureDocument) { + func camera(_ viewController: CameraViewController, didCapture document: GiniCaptureDocument) { let loadingView = viewController.addValidationLoadingView() validate([document]) { result in @@ -50,7 +50,7 @@ extension GiniScreenAPICoordinator: CameraViewControllerDelegate { } } - public func camera(_ viewController: CameraScreen, didSelect documentPicker: DocumentPickerType) { + func camera(_ viewController: CameraViewController, didSelect documentPicker: DocumentPickerType) { switch documentPicker { case .gallery: documentPickerCoordinator.showGalleryPicker(from: viewController) @@ -60,7 +60,7 @@ extension GiniScreenAPICoordinator: CameraViewControllerDelegate { } } - public func cameraDidAppear(_ viewController: CameraScreen) { + func cameraDidAppear(_ viewController: CameraViewController) { if shouldShowOnBoarding() { showOnboardingScreen(cameraViewController: viewController, completion: { viewController.setupCamera() @@ -70,7 +70,7 @@ extension GiniScreenAPICoordinator: CameraViewControllerDelegate { } } - public func cameraDidTapReviewButton(_ viewController: CameraScreen) { + func cameraDidTapReviewButton(_ viewController: CameraViewController) { popBackToReview() } @@ -87,7 +87,7 @@ extension GiniScreenAPICoordinator: CameraViewControllerDelegate { return cameraButtonsViewModel } - func createCameraViewController() -> CameraScreen { + func createCameraViewController() -> CameraViewController { let cameraButtonsViewModel = createCameraButtonsViewModel() let cameraViewController = CameraViewController( @@ -151,7 +151,7 @@ extension GiniScreenAPICoordinator: CameraViewControllerDelegate { } private func showOnboardingScreen( - cameraViewController: CameraScreen, + cameraViewController: CameraViewController, completion: @escaping () -> Void) { cameraViewController.hideCaptureButton() diff --git a/Sources/GiniCaptureSDK/Core/Screens/Screen API Coordinator/GiniScreenAPICoordinator.swift b/Sources/GiniCaptureSDK/Core/Screens/Screen API Coordinator/GiniScreenAPICoordinator.swift index 78fbddc..3664f61 100644 --- a/Sources/GiniCaptureSDK/Core/Screens/Screen API Coordinator/GiniScreenAPICoordinator.swift +++ b/Sources/GiniCaptureSDK/Core/Screens/Screen API Coordinator/GiniScreenAPICoordinator.swift @@ -35,7 +35,7 @@ open class GiniScreenAPICoordinator: NSObject, Coordinator { // Screens var analysisViewController: AnalysisViewController? - weak var cameraScreen: CameraScreen? + weak var cameraScreen: CameraViewController? var noResultsViewController: NoResultScreenViewController? lazy var reviewViewController: ReviewViewController = { return self.createReviewScreenContainer(with: []) @@ -200,7 +200,7 @@ extension GiniScreenAPICoordinator { @objc func back() { switch screenAPINavigationController.topViewController { - case is CameraScreen: + case is CameraViewController: trackingDelegate?.onCameraScreenEvent(event: Event(type: .exit)) if pages.type == .qrcode { @@ -294,7 +294,7 @@ extension GiniScreenAPICoordinator: UINavigationControllerDelegate { } } - if toVC is CameraScreen && + if toVC is CameraViewController && (fromVC is AnalysisViewController || fromVC is NoResultScreenViewController) { // When going directly from the analysis or from the single page review screen to the camera the pages @@ -302,7 +302,7 @@ extension GiniScreenAPICoordinator: UINavigationControllerDelegate { clearDocuments() } - if fromVC is ReviewViewController, let cameraVC = toVC as? CameraScreen { + if fromVC is ReviewViewController, let cameraVC = toVC as? CameraViewController { cameraVC.replaceCapturedStackImages(with: pages.compactMap { $0.document.previewImage }) } diff --git a/Sources/GiniCaptureSDK/GiniCaptureSDKVersion.swift b/Sources/GiniCaptureSDK/GiniCaptureSDKVersion.swift index b3d1df3..0b361cb 100644 --- a/Sources/GiniCaptureSDK/GiniCaptureSDKVersion.swift +++ b/Sources/GiniCaptureSDK/GiniCaptureSDKVersion.swift @@ -5,4 +5,4 @@ // Created by Nadya Karaban on 29.10.21. // -public let GiniCaptureSDKVersion = "3.7.0" +public let GiniCaptureSDKVersion = "3.7.1"