QrCodeReaderController.swift 2.9 KB

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