Skip to content

Commit

Permalink
Merge pull request #132 from psalzAppDev/main
Browse files Browse the repository at this point in the history
Improvement of code readability
  • Loading branch information
nathanfallet committed Apr 13, 2024
2 parents 3038ca7 + 83db36b commit 944a6a1
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 80 deletions.
3 changes: 1 addition & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import PackageDescription
let package = Package(
name: "CodeScanner",
platforms: [
.iOS(.v13),
.macOS(.v11)
.iOS(.v13)
],
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
Expand Down
15 changes: 12 additions & 3 deletions Sources/CodeScanner/CodeScanner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public struct CodeScannerView: UIViewControllerRepresentable {
public let manualSelect: Bool
public let scanInterval: Double
public let showViewfinder: Bool
public let requirePhotoOutput: Bool
public let requiresPhotoOutput: Bool
public var simulatedData = ""
public var shouldVibrateOnSuccess: Bool
public var isTorchOn: Bool
Expand All @@ -96,7 +96,7 @@ public struct CodeScannerView: UIViewControllerRepresentable {
manualSelect: Bool = false,
scanInterval: Double = 2.0,
showViewfinder: Bool = false,
requirePhotoOutput: Bool = true,
requiresPhotoOutput: Bool = true,
simulatedData: String = "",
shouldVibrateOnSuccess: Bool = true,
isTorchOn: Bool = false,
Expand All @@ -109,7 +109,7 @@ public struct CodeScannerView: UIViewControllerRepresentable {
self.scanMode = scanMode
self.manualSelect = manualSelect
self.showViewfinder = showViewfinder
self.requirePhotoOutput = requirePhotoOutput
self.requiresPhotoOutput = requiresPhotoOutput
self.scanInterval = scanInterval
self.simulatedData = simulatedData
self.shouldVibrateOnSuccess = shouldVibrateOnSuccess
Expand All @@ -136,6 +136,15 @@ public struct CodeScannerView: UIViewControllerRepresentable {

}

@available(macCatalyst 14.0, *)
extension CodeScannerView {

@available(*, deprecated, renamed: "requiresPhotoOutput")
public var requirePhotoOutput: Bool {
requiresPhotoOutput
}
}

@available(macCatalyst 14.0, *)
struct CodeScannerView_Previews: PreviewProvider {
static var previews: some View {
Expand Down
154 changes: 79 additions & 75 deletions Sources/CodeScanner/ScannerViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,11 @@ extension CodeScannerView {
previewLayer.frame = view.layer.bounds
previewLayer.videoGravity = .resizeAspectFill
view.layer.addSublayer(previewLayer)
addviewfinder()
addViewFinder()

reset()

if (captureSession.isRunning == false) {
if !captureSession.isRunning {
DispatchQueue.global(qos: .userInteractive).async {
self.captureSession?.startRunning()
}
Expand Down Expand Up @@ -232,7 +232,7 @@ extension CodeScannerView {
NotificationCenter.default.addObserver(
self,
selector: #selector(updateOrientation),
name: Notification.Name("UIDeviceOrientationDidChangeNotification"),
name: UIDevice.orientationDidChangeNotification,
object: nil
)
}
Expand All @@ -257,17 +257,17 @@ extension CodeScannerView {
return
}

if (captureSession!.canAddInput(videoInput)) {
if captureSession!.canAddInput(videoInput) {
captureSession!.addInput(videoInput)
} else {
didFail(reason: .badInput)
return
}
let metadataOutput = AVCaptureMetadataOutput()

if (captureSession!.canAddOutput(metadataOutput)) {
if captureSession!.canAddOutput(metadataOutput) {
captureSession!.addOutput(metadataOutput)
captureSession?.addOutput(photoOutput)
captureSession!.addOutput(photoOutput)
metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
metadataOutput.metadataObjectTypes = parentView.codeTypes
} else {
Expand All @@ -276,7 +276,7 @@ extension CodeScannerView {
}
}

private func addviewfinder() {
private func addViewFinder() {
guard showViewfinder, let imageView = viewFinder else { return }

view.addSubview(imageView)
Expand All @@ -292,7 +292,7 @@ extension CodeScannerView {
override public func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)

if (captureSession?.isRunning == true) {
if captureSession?.isRunning == true {
DispatchQueue.global(qos: .userInteractive).async {
self.captureSession?.stopRunning()
}
Expand Down Expand Up @@ -329,7 +329,7 @@ extension CodeScannerView {
return
}

// Focus to the correct point, make continiuous focus and exposure so the point stays sharp when moving the device closer
// Focus to the correct point, make continuous focus and exposure so the point stays sharp when moving the device closer
device.focusPointOfInterest = focusPoint
device.focusMode = .continuousAutoFocus
device.exposurePointOfInterest = focusPoint
Expand Down Expand Up @@ -383,7 +383,7 @@ extension CodeScannerView {
videoCaptureDevice.unlockForConfiguration()
}

if isGalleryPresented && !isGalleryShowing {
if isGalleryPresented, !isGalleryShowing {
openGallery()
}

Expand All @@ -405,11 +405,11 @@ extension CodeScannerView {
lastTime = Date()
}

func isPastScanInterval() -> Bool {
var isPastScanInterval: Bool {
Date().timeIntervalSince(lastTime) >= parentView.scanInterval
}

func isWithinManualCaptureInterval() -> Bool {
var isWithinManualCaptureInterval: Bool {
Date().timeIntervalSince(lastTime) <= 0.5
}

Expand All @@ -435,53 +435,56 @@ extension CodeScannerView {
@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 !parentView.isPaused && !didFinishScanning && !isCapturing,
let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject,
let stringValue = readableObject.stringValue
else {
return
}

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

switch parentView.scanMode {
case .once:
guard let metadataObject = metadataObjects.first,
!parentView.isPaused,
!didFinishScanning,
!isCapturing,
let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject,
let stringValue = readableObject.stringValue else {

return
}

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)
// 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 .oncePerCode:
if !codesFound.contains(stringValue) {
codesFound.insert(stringValue)
found(result)
}

case .continuous:
if isPastScanInterval() {
found(result)
}
case .continuous:
if isPastScanInterval {
found(result)
}

case .continuousExcept(let ignoredList):
if isPastScanInterval() && !ignoredList.contains(stringValue) {
found(result)
}
case .continuousExcept(let ignoredList):
if isPastScanInterval, !ignoredList.contains(stringValue) {
found(result)
}
}
}

if parentView.requirePhotoOutput {
isCapturing = true
photoOutput.capturePhoto(with: AVCapturePhotoSettings(), delegate: self)
} else {
handler?(nil)
}
if parentView.requiresPhotoOutput {
isCapturing = true
photoOutput.capturePhoto(with: AVCapturePhotoSettings(), delegate: self)
} else {
handler?(nil)
}
}
}
Expand All @@ -493,40 +496,41 @@ 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)
}
defer {
dismiss(animated: true)
}

}
guard let qrcodeImg = info[.originalImage] as? UIImage,
let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: [CIDetectorAccuracy: CIDetectorAccuracyHigh]),
let ciImage = CIImage(image:qrcodeImg) else {

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

dismiss(animated: true, completion: nil)
var qrCodeLink = ""

let features = detector.features(in: ciImage)

for feature in features as! [CIQRCodeFeature] {
qrCodeLink = feature.messageString!
if qrCodeLink.isEmpty {
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)
}
}
}

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

Expand Down

0 comments on commit 944a6a1

Please sign in to comment.