今天来简单讲讲如何在 iOS 中识别二维码。
AVCaptureSession
要在 iOS 中识别二维码,主要用到的是 AVCaptureSession 这个类,首先导入 AVFoundation,然后我们在控制器中创建一个 session 对象:
import AVFoundation
let session = AVCaptureSession()
检查摄像头权限
在开始前,你需要检查是否有摄像头权限:
func checkCameraPermission() {
let authStatus = AVCaptureDevice.authorizationStatus(for: .video)
switch authStatus {
case .authorized:
print("已经授权,可以使用摄像头")
case .denied:
print("用户拒绝授权,无法使用摄像头")
case .restricted:
print("用户无法授权,比如家长控制等情况")
case .notDetermined:
print("用户还没有做出选择")
@unknown default:
print("其他未知情况")
}
}
配置
检查有权限之后需要做一些配置:
func configs() {
/// 获取设备
let discoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: .video, position: .back)
/// 输入和输出
if let firstDevice = discoverySession.devices.first,
let videoInput = try? AVCaptureDeviceInput(device: firstDevice) {
let queue = DispatchQueue.global(qos: .default)
let videoOutput = AVCaptureMetadataOutput()
videoOutput.setMetadataObjectsDelegate(self, queue: queue)
// 堆代码 duidaima.com
// 添加输入
if session.canAddInput(videoInput) {
session.addInput(videoInput)
}
// 添加输出
if session.canAddOutput(videoOutput) {
session.addOutput(videoOutput)
}
/// 设置扫描类型
videoOutput.metadataObjectTypes = [
.qr,
.code39,
.code128,
.code39Mod43,
.ean13,
.ean8,
.code93]
} else {
print("出错")
}
}
添加预览
预览就是把摄像头拍到的内容显示出来,我们这里直接全屏显示:
func addPreview() {
let previewLayer = AVCaptureVideoPreviewLayer(session: session)
previewLayer.frame = view.layer.bounds
previewLayer.videoGravity = .resizeAspectFill
view.layer.addSublayer(previewLayer)
}
开始扫描
之后就可以调用开始扫描的方法了:
session.startRunning()
扫描结果需要实现 AVCaptureMetadataOutputObjectsDelegate 这个代理:
extension ViewController: AVCaptureMetadataOutputObjectsDelegate {
/// 扫描结果回调
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
guard !metadataObjects.isEmpty else {
print("扫描结果为空")
return
}
for object in metadataObjects {
if let obj = object as? AVMetadataMachineReadableCodeObject,
let result = obj.stringValue {
print("扫描结果为:\(result)")
}
}
// 停止扫描
session.stopRunning()
// 扫到之后的操作。。。
}
}
一般来说,扫描到内容之后需要停止 Session 的扫描,并对扫描结果进行处理。