적당한 고통은 희열이다

- 댄 브라운 '다빈치 코드' 중에서

초보 iOS 개발자의 일상/개발 업무

[Swift iOS] 바코드 인식 화면 Barcode / QR reader

hongssup_ 2021. 4. 22. 18:44
반응형

1. info-plist

바코드 인식을 위해 카메라 접근 권한 설정

Privacy - Camera Usage Description 추가해주기

 

2. viewController

 

import AVKit

BarcodeReaderViewController 클래스에 다음변수를 추가해준다. 

var captureSession: AVCaptureSession?
var videoPreviewLayer: AVCaptureVideoPreviewLayer?

viewDidLoad() 혹은 viewWillAppear() 안에 다음 코드를 넣어 카메라 권한 설정에 따라 alert를 띄워준다.

허용시에는 카메라로 바코드 인식 실행. 

let status = AVCaptureDevice.authorizationStatus(for: .video)
if (status == .authorized) {
    setBarcodeReader()
    setCenterGuideLineView()
} else if (status == .denied) {
    let alert = UIAlertController(title: "알림", message: "바코드 촬영을 위해 카메라 권한이 필요합니다.\n설정 > 어플리케이션에서 카메라 권한을 허용으로 변경해주세요.", preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "확인", style: .default, handler: nil))
    self.present(alert, animated: true, completion: nil)
} else if (status == .notDetermined) {
    AVCaptureDevice.requestAccess(for: .video) { (isSuccess) in
        if (isSuccess) {
            DispatchQueue.main.async {
                self.setBarcodeReader()
            }
        } else {
            DispatchQueue.main.async {
                let alert = UIAlertController(title: "알림", message: "바코드 촬영을 위해 카메라 권한이 필요합니다.\n설정 > 어플리케이션에서 카메라 권한을 허용으로 변경해주세요.", preferredStyle: .alert)
                alert.addAction(UIAlertAction(title: "확인", style: .default, handler: nil))
                self.present(alert, animated: true, completion: nil)
            }
        }
    }
}

카메라로 바코드 인식을 실행할 setBarcodeReader() 메서드

func setBarcodeReader() {
    let captureDevice = AVCaptureDevice.default(for: AVMediaType.video)
    if let captureDevice = captureDevice {
        do {
            captureSession = AVCaptureSession()
            
            let input: AVCaptureDeviceInput
            input = try AVCaptureDeviceInput(device: captureDevice)
            
            captureSession?.addInput(input)
            
            let metadataOutput = AVCaptureMetadataOutput()
            
            captureSession?.addOutput(metadataOutput)
            metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
            metadataOutput.metadataObjectTypes = [.ean13]	//바코드 형식에 따라 다름
            
            //captureSession?.startRunning()
            
            videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession!)
            videoPreviewLayer?.videoGravity = .resizeAspectFill
            videoPreviewLayer?.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height)
            view.layer.addSublayer(videoPreviewLayer!)
            
            captureSession?.startRunning()
            setCenterGuideLineView()
        } catch {
            print("error")
        }
    }
    
}

 

바코드 인식 클래스에 extension으로 AVCaptureMetadataOutputObjectsDelegate 프로토콜 추가해주고

metadataOutput 메서드로 결과값을 처리해준다. 

func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
    captureSession?.stopRunning()
    
    if metadataObjects.count == 0 {
        return
    }
    
    let metaDataObject = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
    
    guard let StringCodeValue = metaDataObject.stringValue else {
        return
    }
    
    guard let _ = self.videoPreviewLayer?.transformedMetadataObject(for: metaDataObject) else {
        return
    }
 
    print(StringCodeValue)
    
}

 

728x90
반응형