QrCodeReaderController.swift 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import AVFoundation
  2. import UIKit
  3. class QrCodeReaderController: UIViewController {
  4. var captureSession = AVCaptureSession()
  5. var videoPreviewLayer: AVCaptureVideoPreviewLayer?
  6. weak var delegate: QrCodeReaderDelegate?
  7. private let supportedCodeTypes = [
  8. AVMetadataObject.ObjectType.qr
  9. ]
  10. override func viewDidLoad() {
  11. super.viewDidLoad()
  12. self.edgesForExtendedLayout = []
  13. title = String.localized("qrscan_title")
  14. guard let captureDevice = AVCaptureDevice.DiscoverySession.init(
  15. deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera],
  16. mediaType: .video,
  17. position: .back).devices.first else {
  18. print("Failed to get the camera device")
  19. return
  20. }
  21. do {
  22. let input = try AVCaptureDeviceInput(device: captureDevice)
  23. captureSession.addInput(input)
  24. let captureMetadataOutput = AVCaptureMetadataOutput()
  25. captureSession.addOutput(captureMetadataOutput)
  26. captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
  27. captureMetadataOutput.metadataObjectTypes = supportedCodeTypes
  28. } catch {
  29. // If any error occurs, simply print it out and don't continue any more.
  30. logger.error("failed to setup QR Code Scanner: \(error)")
  31. return
  32. }
  33. videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
  34. videoPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
  35. videoPreviewLayer?.frame = view.layer.bounds
  36. view.layer.addSublayer(videoPreviewLayer!)
  37. let infoLabel = createInfoLabel()
  38. view.addSubview(infoLabel)
  39. view.addConstraint(infoLabel.constraintAlignBottomTo(view, paddingBottom: 8))
  40. view.addConstraint(infoLabel.constraintCenterXTo(view))
  41. view.bringSubviewToFront(infoLabel)
  42. }
  43. private func createInfoLabel() -> UIView {
  44. let label = UILabel()
  45. label.translatesAutoresizingMaskIntoConstraints = false
  46. label.text = String.localized("qrscan_hint")
  47. label.lineBreakMode = .byWordWrapping
  48. label.numberOfLines = 0
  49. label.textAlignment = .center
  50. label.textColor = .white
  51. return label
  52. }
  53. override func viewWillAppear(_ animated: Bool) {
  54. captureSession.startRunning()
  55. }
  56. override func viewWillDisappear(_ animated: Bool) {
  57. captureSession.stopRunning()
  58. }
  59. override func didReceiveMemoryWarning() {
  60. super.didReceiveMemoryWarning()
  61. // Dispose of any resources that can be recreated.
  62. }
  63. }
  64. extension QrCodeReaderController: AVCaptureMetadataOutputObjectsDelegate {
  65. func metadataOutput(_: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from _: AVCaptureConnection) {
  66. let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
  67. if supportedCodeTypes.contains(metadataObj.type) {
  68. if metadataObj.stringValue != nil {
  69. self.delegate?.handleQrCode(metadataObj.stringValue!)
  70. }
  71. }
  72. }
  73. }