Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvement of code readability #132

Merged
merged 4 commits into from
Apr 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
nathanfallet marked this conversation as resolved.
Show resolved Hide resolved
.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
}
nathanfallet marked this conversation as resolved.
Show resolved Hide resolved

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
Loading