How to scan QRCode with SwiftUI
SwiftUI + UIViewControllerRepresentable scanning QRCode
- Xcode version: 11.0 beta 4
- macOS version: 10.15 Beta
Prerequisites
This blog post is a demo for integrating a custom UIViewController with SwiftUI using the Coordinator pattern, which I think is really awesome - with SwiftUI you can build nice UI very easily and leave the backend implementation fallback to UIKit and bridging them together using UIViewControllerRepresentable
and in the Coordinator you create the delegates/datasources so that the data can be passed back from a UIViewController to the SwiftUI @State
or elsewhere.
Get Started
Create the ViewController that does the scan
This part is quite simple, just copy and paste the demo code from here into a new file, say, ScannerViewController
And make two changes:
- Add a new delegate for SwiftUI. Add a new line after:
var previewLayer: AVCaptureVideoPreviewLayer!
So it becomes:
var previewLayer: AVCaptureVideoPreviewLayer!
var delegate: QRCodeScannerDelegate?
- Change the
found
function from
func found(code: String) {
print(code)
}
to
func found(code: String) {
self.delegate?.codeDidFind(code)
}
Now create a delegate protocol in the same file:
protocol QRCodeScannerDelegate {
func codeDidFind(_ code: String)
}
Now we are done with the ViewController, let's go back to the SwiftUI part!
Create the UIViewControllerRepresentable
Create a new file, named QRCodeScane.swift
with this content:
import SwiftUI
struct QRCodeScan: UIViewControllerRepresentable {
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIViewController(context: Context) -> QRCodeScanVC {
let vc = QRCodeScanVC()
vc.delegate = context.coordinator
return vc
}
func updateUIViewController(_ vc: QRCodeScanVC, context: Context) {
}
class Coordinator: NSObject, QRCodeScannerDelegate {
func codeDidFind(_ code: String) {
print(code)
}
var parent: QRCodeScan
init(_ parent: QRCodeScan) {
self.parent = parent
}
}
}
#if DEBUG
struct QRCodeScan_Previews: PreviewProvider {
static var previews: some View {
QRCodeScan()
}
}
#endif
In the sample, we made the Coordinator
implement the QRCodeScannerDelegate
protocol that we just created earlier.
We are done!