Skip to content

Commit

Permalink
Merge pull request #125 from qalandarov/separate-delegates
Browse files Browse the repository at this point in the history
Separate delegates into extensions
  • Loading branch information
nathanfallet authored Feb 23, 2024
2 parents 7da6b1e + 5a49d03 commit e1943d7
Showing 1 changed file with 106 additions and 87 deletions.
193 changes: 106 additions & 87 deletions Sources/CodeScanner/ScannerViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import UIKit
@available(macCatalyst 14.0, *)
extension CodeScannerView {

public class ScannerViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, AVCaptureMetadataOutputObjectsDelegate, UIAdaptivePresentationControllerDelegate {
public class ScannerViewController: UIViewController, UINavigationControllerDelegate {
private let photoOutput = AVCapturePhotoOutput()
private var isCapturing = false
private var handler: ((UIImage) -> Void)?
Expand Down Expand Up @@ -56,50 +56,6 @@ extension CodeScannerView {
openGallery()
}

public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
isGalleryShowing = false

if let qrcodeImg = info[.originalImage] as? UIImage {
let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: [CIDetectorAccuracy: CIDetectorAccuracyHigh])!
let ciImage = CIImage(image:qrcodeImg)!
var qrCodeLink = ""

let features = detector.features(in: ciImage)

for feature in features as! [CIQRCodeFeature] {
qrCodeLink = feature.messageString!
if qrCodeLink == "" {
didFail(reason: .badOutput)
} else {
let corners = [
feature.bottomLeft,
feature.bottomRight,
feature.topRight,
feature.topLeft
]
let result = ScanResult(string: qrCodeLink, type: .qr, image: qrcodeImg, corners: corners)
found(result)
}

}

} else {
print("Something went wrong")
}

dismiss(animated: true, completion: nil)
}

public func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
isGalleryShowing = false
dismiss(animated: true, completion: nil)
}

public func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
// Gallery is no longer being presented
isGalleryShowing = false
}

#if targetEnvironment(simulator)
override public func loadView() {
view = UIView()
Expand Down Expand Up @@ -449,48 +405,6 @@ extension CodeScannerView {
lastTime = Date()
}

public func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
if let metadataObject = metadataObjects.first {
guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }
guard let stringValue = readableObject.stringValue else { return }

guard didFinishScanning == false else { return }

let photoSettings = AVCapturePhotoSettings()
guard !isCapturing else { return }
isCapturing = true

handler = { [self] image in
let result = ScanResult(string: stringValue, type: readableObject.type, image: image, corners: readableObject.corners)

switch parentView.scanMode {
case .once:
found(result)
// make sure we only trigger scan once per use
didFinishScanning = true

case .manual:
if !didFinishScanning, isWithinManualCaptureInterval() {
found(result)
didFinishScanning = true
}

case .oncePerCode:
if !codesFound.contains(stringValue) {
codesFound.insert(stringValue)
found(result)
}

case .continuous:
if isPastScanInterval() {
found(result)
}
}
}
photoOutput.capturePhoto(with: photoSettings, delegate: self)
}
}

func isPastScanInterval() -> Bool {
Date().timeIntervalSince(lastTime) >= parentView.scanInterval
}
Expand All @@ -516,6 +430,109 @@ extension CodeScannerView {
}
}

// MARK: - AVCaptureMetadataOutputObjectsDelegate

@available(macCatalyst 14.0, *)
extension CodeScannerView.ScannerViewController: AVCaptureMetadataOutputObjectsDelegate {
public func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
if let metadataObject = metadataObjects.first {
guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }
guard let stringValue = readableObject.stringValue else { return }

guard didFinishScanning == false else { return }

let photoSettings = AVCapturePhotoSettings()
guard !isCapturing else { return }
isCapturing = true

handler = { [self] image in
let result = ScanResult(string: stringValue, type: readableObject.type, image: image, corners: readableObject.corners)

switch parentView.scanMode {
case .once:
found(result)
// make sure we only trigger scan once per use
didFinishScanning = true

case .manual:
if !didFinishScanning, isWithinManualCaptureInterval() {
found(result)
didFinishScanning = true
}

case .oncePerCode:
if !codesFound.contains(stringValue) {
codesFound.insert(stringValue)
found(result)
}

case .continuous:
if isPastScanInterval() {
found(result)
}
}
}
photoOutput.capturePhoto(with: photoSettings, delegate: self)
}
}
}

// MARK: - UIImagePickerControllerDelegate

@available(macCatalyst 14.0, *)
extension CodeScannerView.ScannerViewController: UIImagePickerControllerDelegate {
public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
isGalleryShowing = false

if let qrcodeImg = info[.originalImage] as? UIImage {
let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: [CIDetectorAccuracy: CIDetectorAccuracyHigh])!
let ciImage = CIImage(image:qrcodeImg)!
var qrCodeLink = ""

let features = detector.features(in: ciImage)

for feature in features as! [CIQRCodeFeature] {
qrCodeLink = feature.messageString!
if qrCodeLink == "" {
didFail(reason: .badOutput)
} else {
let corners = [
feature.bottomLeft,
feature.bottomRight,
feature.topRight,
feature.topLeft
]
let result = ScanResult(string: qrCodeLink, type: .qr, image: qrcodeImg, corners: corners)
found(result)
}

}

} else {
print("Something went wrong")
}

dismiss(animated: true, completion: nil)
}

public func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
isGalleryShowing = false
dismiss(animated: true, completion: nil)
}
}

// MARK: - UIAdaptivePresentationControllerDelegate

@available(macCatalyst 14.0, *)
extension CodeScannerView.ScannerViewController: UIAdaptivePresentationControllerDelegate {
public func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
// Gallery is no longer being presented
isGalleryShowing = false
}
}

// MARK: - AVCapturePhotoCaptureDelegate

@available(macCatalyst 14.0, *)
extension CodeScannerView.ScannerViewController: AVCapturePhotoCaptureDelegate {

Expand Down Expand Up @@ -552,6 +569,8 @@ extension CodeScannerView.ScannerViewController: AVCapturePhotoCaptureDelegate {

}

// MARK: - AVCaptureDevice

@available(macCatalyst 14.0, *)
public extension AVCaptureDevice {

Expand Down

0 comments on commit e1943d7

Please sign in to comment.