QrCodeReaderController.swift 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. //
  2. // QrCodeReaderController.swift
  3. // deltachat-ios
  4. //
  5. // Created by Friedel Ziegelmayer on 28.12.18.
  6. // Copyright © 2018 Jonas Reinsch. All rights reserved.
  7. //
  8. import AVFoundation
  9. import UIKit
  10. protocol QrCodeReaderDelegate: class {
  11. func handleQrCode(_ code: String)
  12. }
  13. class QrCodeReaderController: UIViewController {
  14. var captureSession = AVCaptureSession()
  15. var videoPreviewLayer: AVCaptureVideoPreviewLayer?
  16. var qrCodeFrameView: UIView?
  17. weak var delegate: QrCodeReaderDelegate?
  18. private let supportedCodeTypes = [
  19. AVMetadataObject.ObjectType.qr,
  20. ]
  21. override func viewDidLoad() {
  22. super.viewDidLoad()
  23. let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(
  24. deviceTypes: [.builtInDualCamera],
  25. mediaType: AVMediaType.video,
  26. position: .back
  27. )
  28. guard let captureDevice = deviceDiscoverySession.devices.first else {
  29. print("Failed to get the camera device")
  30. return
  31. }
  32. do {
  33. let input = try AVCaptureDeviceInput(device: captureDevice)
  34. captureSession.addInput(input)
  35. let captureMetadataOutput = AVCaptureMetadataOutput()
  36. captureSession.addOutput(captureMetadataOutput)
  37. captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
  38. captureMetadataOutput.metadataObjectTypes = supportedCodeTypes
  39. } catch {
  40. // If any error occurs, simply print it out and don't continue any more.
  41. logger.error("failed to setup QR Code Scanner: \(error)")
  42. return
  43. }
  44. videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
  45. videoPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
  46. videoPreviewLayer?.frame = view.layer.bounds
  47. view.layer.addSublayer(videoPreviewLayer!)
  48. captureSession.startRunning()
  49. qrCodeFrameView = UIView()
  50. if let qrCodeFrameView = qrCodeFrameView {
  51. qrCodeFrameView.layer.borderColor = UIColor.green.cgColor
  52. qrCodeFrameView.layer.borderWidth = 2
  53. view.addSubview(qrCodeFrameView)
  54. view.bringSubviewToFront(qrCodeFrameView)
  55. }
  56. }
  57. override func didReceiveMemoryWarning() {
  58. super.didReceiveMemoryWarning()
  59. // Dispose of any resources that can be recreated.
  60. }
  61. }
  62. extension QrCodeReaderController: AVCaptureMetadataOutputObjectsDelegate {
  63. func metadataOutput(_: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from _: AVCaptureConnection) {
  64. if metadataObjects.isEmpty {
  65. qrCodeFrameView?.frame = CGRect.zero
  66. return
  67. }
  68. let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
  69. if supportedCodeTypes.contains(metadataObj.type) {
  70. let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj)
  71. qrCodeFrameView?.frame = barCodeObject!.bounds
  72. if metadataObj.stringValue != nil {
  73. DispatchQueue.main.async {
  74. self.captureSession.stopRunning()
  75. self.dismiss(animated: true) {
  76. self.delegate?.handleQrCode(metadataObj.stringValue!)
  77. }
  78. }
  79. }
  80. }
  81. }
  82. }