Swift / iOSでQRコードを読み取る

AVFoundationでのやり方

AVCaptureMetadataOutputObjectsDelegateの

>func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection)

という名前のデリゲートメソッドで毎フレームのQRコード検出結果が得られます。

以下はカメラ設定とQRコード検出のコードで、これでとりあえずQRコードの領域描画ができます。

![Dec-18-2023 22-04-59.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/9e555ede-0703-ed0a-b455-763618d02a9b.gif)

```swift

class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
    private var captureSession: AVCaptureSession!
    private var preview = UIView()
    private lazy var previewLayer: AVCaptureVideoPreviewLayer = {
        let layer = AVCaptureVideoPreviewLayer(session: self.captureSession)
        layer.frame = preview.bounds
        layer.videoGravity = .resizeAspectFill
        layer.connection?.videoOrientation = .portrait
        return layer
    }()
    private var qrCodeFrameView = UIView()
    var qrCodeLabel = UILabel()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(preview)
        preview.frame = view.bounds
        qrCodeFrameView.layer.borderColor = UIColor.red.cgColor
        qrCodeFrameView.layer.borderWidth = 2
        view.addSubview(qrCodeFrameView)
        view.bringSubviewToFront(qrCodeFrameView)
        qrCodeFrameView.isHidden = true
        view.addSubview(qrCodeLabel)
        let captureDevice = AVCaptureDevice.default(for: .video)
        
        do {
            let input = try AVCaptureDeviceInput(device: captureDevice!)
            captureSession = AVCaptureSession()
            captureSession?.addInput(input)
            
            let output = AVCaptureMetadataOutput()
            captureSession?.addOutput(output)
            
            output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
            output.metadataObjectTypes = [.qr]
            preview.layer.addSublayer(previewLayer)
            DispatchQueue.global(qos: .userInitiated).async {
                self.captureSession?.startRunning()
            }
        } catch {
            print("Error setting up capture session: \(error.localizedDescription)")
        }
    }

    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
    if let metadataObject = metadataObjects.first {
        guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }
        
        if let stringValue = readableObject.stringValue {
            print("QR Code Value: \(stringValue)")
            DispatchQueue.main.async {
                self.qrCodeLabel.text = stringValue
            }
        }
        
        if let barCodeObject = previewLayer.transformedMetadataObject(for: metadataObject) {
            print(barCodeObject)
            let qrCodeFrame = barCodeObject.bounds
            DispatchQueue.main.async {
                self.qrCodeLabel.isHidden = false
                self.qrCodeFrameView.isHidden = false
                self.qrCodeFrameView.frame = qrCodeFrame
                self.qrCodeLabel.frame = CGRect(x: self.qrCodeFrameView.frame.minX, y: self.qrCodeFrameView.frame.minY-60, width: 300, height: 60)
            }
        } else {
            DispatchQueue.main.async {
                self.qrCodeFrameView.isHidden = true
            }
        }
    }
}
```

🐣
****
フリーランスエンジニアです。
AIについて色々記事を書いていますのでよかったらプロフィールを見てみてください。

もし以下のようなご要望をお持ちでしたらお気軽にご相談ください。
AIサービスを開発したい、ビジネスにAIを組み込んで効率化したい、AIを使ったスマホアプリを開発したい、
ARを使ったアプリケーションを作りたい、スマホアプリを作りたいけどどこに相談したらいいかわからない…

いずれも中間コストを省いたリーズナブルな価格でお請けできます。

お仕事のご相談はこちらまで
rockyshikoku@gmail.com

機械学習やAR技術を使ったアプリケーションを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)