iOS16以前はAVFoundationを用いてQRコードの読み取りを実装していました。しかし、iOS16からはVisionKitの新機能により、より簡単な方法でQRコードのスキャンが可能になりました。
VisionKitは、機械学習を活用した画像認識技術を提供しており、これにより容易に高品質なデータ認識機能をアプリに組み込むことができます。
忘れないように備忘録として実装方法を残しておきます。
実装
以下が実装です。 SwiftUIで使用できるようにUIViewControllerRepresentableでラップしています。
import VisionKit
import UIKit
import SwiftUI
public struct QRCodeReader: UIViewControllerRepresentable {
private let onRecognize: (RecognizedItem.Barcode) -> Void
public init(onRecognize: @escaping (RecognizedItem.Barcode) -> Void) {
self.onRecognize = onRecognize
}
public func makeUIViewController(context: Context) -> some UIViewController {
let viewController = DataScannerViewController(
recognizedDataTypes: [.barcode(symbologies: [.qr])],
qualityLevel: .balanced,
recognizesMultipleItems: false,
isHighFrameRateTrackingEnabled: false,
isHighlightingEnabled: true
)
viewController.delegate = context.coordinator
try? viewController.startScanning()
return viewController
}
public func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
}
public func makeCoordinator() -> Coordinator {
Coordinator(parent: self)
}
public final class Coordinator: NSObject, DataScannerViewControllerDelegate {
let parent: QRCodeReader
fileprivate init(parent: QRCodeReader) {
self.parent = parent
}
public func dataScanner(_ dataScanner: DataScannerViewController, didAdd addedItems: [RecognizedItem], allItems: [RecognizedItem]) {
guard let item = allItems.first else { return }
switch item {
case .barcode(let recognizedCode):
parent.onRecognize(recognizedCode)
default:
break
}
}
}
}
Coordinatorを使用して、認識したQRコードをQRCodeViewのonRecognizeクロージャでコールバックしています。
ちなみにDataScannerViewControllerは、QRコードだけでなく、他の種類のバーコードやテキストの認識などもサポートしています。