-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Rename to RootView to match Android * Add OnboardingScreen * iOS 14 * ignoresSafeArea * remove redundant comment * Add QR code scanning * Add viewfinder * Restore smile_config for sample app
- Loading branch information
Showing
16 changed files
with
900 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
// swiftlint:disable all | ||
// MIT License: https://github.com/twostraws/CodeScanner/blob/main/LICENSE | ||
// CodeScanner.swift | ||
// https://github.com/twostraws/CodeScanner | ||
// | ||
// Created by Paul Hudson on 14/12/2021. | ||
// Copyright © 2021 Paul Hudson. All rights reserved. | ||
// | ||
|
||
import AVFoundation | ||
import SwiftUI | ||
|
||
/// An enum describing the ways CodeScannerView can hit scanning problems. | ||
public enum ScanError: Error { | ||
/// The camera could not be accessed. | ||
case badInput | ||
|
||
/// The camera was not capable of scanning the requested codes. | ||
case badOutput | ||
|
||
/// Initialization failed. | ||
case initError(_ error: Error) | ||
|
||
/// The camera permission is denied | ||
case permissionDenied | ||
} | ||
|
||
/// The result from a successful scan: the string that was scanned, and also the type of data that was found. | ||
/// The type is useful for times when you've asked to scan several different code types at the same time, because | ||
/// it will report the exact code type that was found. | ||
@available(macCatalyst 14.0, *) | ||
public struct ScanResult { | ||
/// The contents of the code. | ||
public let string: String | ||
|
||
/// The type of code that was matched. | ||
public let type: AVMetadataObject.ObjectType | ||
|
||
/// The image of the code that was matched | ||
public let image: UIImage? | ||
|
||
/// The corner coordinates of the scanned code. | ||
public let corners: [CGPoint] | ||
} | ||
|
||
/// The operating mode for CodeScannerView. | ||
public enum ScanMode { | ||
/// Scan exactly one code, then stop. | ||
case once | ||
|
||
/// Scan each code no more than once. | ||
case oncePerCode | ||
|
||
/// Keep scanning all codes until dismissed. | ||
case continuous | ||
|
||
/// Scan only when capture button is tapped. | ||
case manual | ||
} | ||
|
||
/// A SwiftUI view that is able to scan barcodes, QR codes, and more, and send back what was found. | ||
/// To use, set `codeTypes` to be an array of things to scan for, e.g. `[.qr]`, and set `completion` to | ||
/// a closure that will be called when scanning has finished. This will be sent the string that was detected or a `ScanError`. | ||
/// For testing inside the simulator, set the `simulatedData` property to some test data you want to send back. | ||
@available(macCatalyst 14.0, *) | ||
public struct CodeScannerView: UIViewControllerRepresentable { | ||
|
||
public let codeTypes: [AVMetadataObject.ObjectType] | ||
public let scanMode: ScanMode | ||
public let manualSelect: Bool | ||
public let scanInterval: Double | ||
public let showViewfinder: Bool | ||
public var simulatedData = "" | ||
public var shouldVibrateOnSuccess: Bool | ||
public var isTorchOn: Bool | ||
public var isGalleryPresented: Binding<Bool> | ||
public var videoCaptureDevice: AVCaptureDevice? | ||
public var completion: (Result<ScanResult, ScanError>) -> Void | ||
|
||
public init( | ||
codeTypes: [AVMetadataObject.ObjectType], | ||
scanMode: ScanMode = .once, | ||
manualSelect: Bool = false, | ||
scanInterval: Double = 2.0, | ||
showViewfinder: Bool = false, | ||
simulatedData: String = "", | ||
shouldVibrateOnSuccess: Bool = true, | ||
isTorchOn: Bool = false, | ||
isGalleryPresented: Binding<Bool> = .constant(false), | ||
videoCaptureDevice: AVCaptureDevice? = AVCaptureDevice.bestForVideo, | ||
completion: @escaping (Result<ScanResult, ScanError>) -> Void | ||
) { | ||
self.codeTypes = codeTypes | ||
self.scanMode = scanMode | ||
self.manualSelect = manualSelect | ||
self.showViewfinder = showViewfinder | ||
self.scanInterval = scanInterval | ||
self.simulatedData = simulatedData | ||
self.shouldVibrateOnSuccess = shouldVibrateOnSuccess | ||
self.isTorchOn = isTorchOn | ||
self.isGalleryPresented = isGalleryPresented | ||
self.videoCaptureDevice = videoCaptureDevice | ||
self.completion = completion | ||
} | ||
|
||
public func makeUIViewController(context: Context) -> ScannerViewController { | ||
return ScannerViewController(showViewfinder: showViewfinder, parentView: self) | ||
} | ||
|
||
public func updateUIViewController(_ uiViewController: ScannerViewController, context: Context) { | ||
uiViewController.parentView = self | ||
uiViewController.updateViewController( | ||
isTorchOn: isTorchOn, | ||
isGalleryPresented: isGalleryPresented.wrappedValue, | ||
isManualCapture: scanMode == .manual, | ||
isManualSelect: manualSelect | ||
) | ||
} | ||
} | ||
|
||
@available(macCatalyst 14.0, *) | ||
struct CodeScannerView_Previews: PreviewProvider { | ||
static var previews: some View { | ||
CodeScannerView(codeTypes: [.qr]) { result in | ||
// do nothing | ||
} | ||
} | ||
} |
Oops, something went wrong.