えむじぃのアプリ開発

えむじぃのアプリ開発

元大手IT企業SE、現ベンチャー企業CTOのブログです。

【Swift】QRコードを読み取る方法

今回はQRコードを読み取る方法をこの記事で説明します。

この記事のポイント・ info.plistを設定
・AVFoundationを使用
・AVCaptureMetadataOutputObjectsDelegateを使用

QRコードを読み取る方法

QRコードを読み取る方法を実装するには以下のように設定します。

info.plist

Privacy - Camera Usage Description ※ここ大事です。

ViewController

AVFoundationのインポート

import AVFoundation

 

Classの変更

class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate 

 

変数の宣言

let captureSession = AVCaptureSession()
var videoPreviewLayer:AVCaptureVideoPreviewLayer?
var qrCodeFrameView:UIView?

viewDidLoad

カメラの設定

let deviceDiscoverySession = 
    AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera],
    mediaType: AVMediaType.video, position: .back)
guard let captureDevice = deviceDiscoverySession.devices.first else {
    print("Error")
    return
}

do {
    let input = try AVCaptureDeviceInput(device: captureDevice)
    captureSession.addInput(input)
    let captureMetadataOutput = AVCaptureMetadataOutput()
    captureSession.addOutput(captureMetadataOutput)

    captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
    captureMetadataOutput.metadataObjectTypes = [AVMetadataObject.ObjectType.qr]

    videoPreviewLayer = AVCaptureVideoPreviewLayer.init(session: captureSession)
    videoPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
    videoPreviewLayer?.frame = view.layer.bounds
    view.layer.addSublayer(videoPreviewLayer!)

    self.captureSession.startRunning()
    view.bringSubview(toFront: messageLabel)
    view.bringSubview(toFront: topbar)

    qrCodeFrameView = UIView()
} catch {
    print(error)
    return
}

Decode

QRコードのデコード処理を追加

func metadataOutput(_ output: AVCaptureMetadataOutput,
    didOutput metadataObjects: [AVMetadataObject],
    from connection: AVCaptureConnection) {
    if metadataObjects.count == 0 {
        qrCodeFrameView?.frame = CGRect.zero
        return
    }

    let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
    if metadataObj.type == AVMetadataObject.ObjectType.qr {
        let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj)
        qrCodeFrameView?.frame = barCodeObject!.bounds

        if metadataObj.stringValue != nil {
           messageLabel.text = metadataObj.stringValue
        }
    }
}

これでQRコードを読み取ることができます。