iOS自带原生二维码扫描的实现

下面就是详细讲解iOS自带原生二维码扫描的实现的完整攻略:

一、引入AVFoundation库

首先,我们需要引入AVFoundation库,来实现二维码扫描。在xcode中选择你项目的targets中的Build Phases,在Link Binary With Libraries中添加AVFoundation.framework。

二、继承AVCaptureSession,创建二维码捕捉器

我们需要继承AVCaptureSession,并创建一个二维码捕捉器来扫描二维码。可以看下面的示例:

import AVFoundation

class QRCodeScanner {
    let captureSession = AVCaptureSession()
    var previewLayer: AVCaptureVideoPreviewLayer?

    init() {
        guard let captureDevice = AVCaptureDevice.default(for: .video),
            let input = try? AVCaptureDeviceInput(device: captureDevice) else {
            return
        }

        let captureMetadataOutput = AVCaptureMetadataOutput()
        captureSession.addInput(input)
        captureSession.addOutput(captureMetadataOutput)

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

        let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        previewLayer.videoGravity = .resizeAspectFill
        self.previewLayer = previewLayer
    }
}

以上代码中,我们使用AVCaptureSession来创建了一个二维码捕捉器QRCodeScanner。先检测一下设备是否有摄像头,并创建AVCaptureDeviceInput输入设备。然后,创建AVCaptureMetadataOutput对象来检测捕捉到的二维码。最后,创建了一个AVCaptureVideoPreviewLayer预览图层并添加到self.previewLayer中。

三、实现AVCaptureMetadataOutputObjectsDelegate代理方法

接下来,我们需要实现AVCaptureMetadataOutputObjectsDelegate代理方法,来处理捕捉到的二维码。具体代码如下:

extension QRCodeScanner: AVCaptureMetadataOutputObjectsDelegate {
    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        guard let metadataObject = metadataObjects.first as? AVMetadataMachineReadableCodeObject,
            let stringValue = metadataObject.stringValue,
            metadataObject.type == .qr else {
            return
        }

        // 二维码扫描成功,可以在这里执行回调
    }
}

以上代码中,我们处理捕捉到的AVMetadataObject,将其转换为二维码AVMetadataMachineReadableCodeObject对象,并获取到二维码的stringValue,来完成二维码的扫描。如果扫描的不是二维码,则直接返回。

四、启动二维码扫描

在上面的QRCodeScanner实现中,我们创建好了AVCaptureSession的输入和输出,以及预览图层。接下来,启动二维码扫描即可:

class ViewController: UIViewController {

    private var qrCodeScanner: QRCodeScanner!

    override func viewDidLoad() {
        super.viewDidLoad()
        qrCodeScanner = QRCodeScanner()

        guard let previewLayer = qrCodeScanner.previewLayer else { return }
        previewLayer.frame = view.layer.bounds
        view.layer.addSublayer(previewLayer)

        qrCodeScanner.captureSession.startRunning()
    }
}

在上面代码中,我们创建了一个QRCodeScanner对象qrCodeScanner,并把预览图层添加到UIViewController的view上。最后,启动QRCodeScanner的捕捉器captureSession即可。

五、示例说明

接下来,我给你两个示例,具体实现请参考上面的完整攻略:

示例1:在UIAlertController中展示扫描到的二维码

在QRCodeScanner中实现接口扫描结束的回调

class QRCodeScanner {
    var onQRCodeScanned: ((String) -> Void)?

    // ...

    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        guard let metadataObject = metadataObjects.first as? AVMetadataMachineReadableCodeObject,
            let stringValue = metadataObject.stringValue,
            metadataObject.type == .qr else {
            return
        }

        // 扫描到二维码,执行回调
        onQRCodeScanned?(stringValue)
    }
}

在UIViewController中弹出UIAlertController,展示扫描到的二维码

class ViewController: UIViewController {

    private var qrCodeScanner: QRCodeScanner!

    override func viewDidLoad() {
        super.viewDidLoad()
        qrCodeScanner = QRCodeScanner()

        qrCodeScanner.onQRCodeScanned = { [weak self] qrCodeString in
            self?.showQRCodeInfo(qrCodeString)
        }

        guard let previewLayer = qrCodeScanner.previewLayer else { return }
        previewLayer.frame = view.layer.bounds
        view.layer.addSublayer(previewLayer)

        qrCodeScanner.captureSession.startRunning()
    }

    private func showQRCodeInfo(_ qrCodeInfo: String) {
        let alertController = UIAlertController(title: "扫描到的二维码", message: qrCodeInfo, preferredStyle: .alert)
        let okAction = UIAlertAction(title: "确定", style: .default, handler: nil)
        alertController.addAction(okAction)

        present(alertController, animated: true, completion: nil)
    }
}

示例2:在UITableView中展示扫描到的二维码

在QRCodeScanner中实现接口扫描结束的回调

class QRCodeScanner {
    var onQRCodeScanned: ((String) -> Void)?

    // ...

    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        guard let metadataObject = metadataObjects.first as? AVMetadataMachineReadableCodeObject,
            let stringValue = metadataObject.stringValue,
            metadataObject.type == .qr else {
            return
        }

        // 扫描到二维码,执行回调
        onQRCodeScanned?(stringValue)
    }
}

在UIViewController中添加UITableView,并更新数据源展示二维码信息

class ViewController: UIViewController {

    private var qrCodeScanner: QRCodeScanner!
    private var qrCodeStrings = [String]() {
        didSet {
            tableView.reloadData()
        }
    }
    private let tableView = UITableView()

    override func viewDidLoad() {
        super.viewDidLoad()
        qrCodeScanner = QRCodeScanner()

        qrCodeScanner.onQRCodeScanned = { [weak self] qrCodeString in
            self?.qrCodeStrings.append(qrCodeString)
        }

        guard let previewLayer = qrCodeScanner.previewLayer else { return }
        previewLayer.frame = view.layer.bounds
        view.layer.addSublayer(previewLayer)

        qrCodeScanner.captureSession.startRunning()

        setupTableView()
    }

    private func setupTableView() {
        view.addSubview(tableView)
        tableView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            tableView.topAnchor.constraint(equalTo: view.topAnchor),
            tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
        ])
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "qrCodeCell")
        tableView.dataSource = self
    }
}

extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return qrCodeStrings.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "qrCodeCell", for: indexPath)
        let qrCodeString = qrCodeStrings[indexPath.row]
        cell.textLabel?.text = qrCodeString
        return cell
    }
}

以上示例代码很简单,你可以尝试在自己的项目中按照上述方法实现iOS自带原生二维码扫描。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:iOS自带原生二维码扫描的实现 - Python技术站

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • 白平衡之灰度世界算法

    背景 在数字图像处理中,白平衡是一种用于调整图像颜色平衡的技术。它可以帮助我们消除图像中的色偏,使图像看起来更加自然。灰度世界算法是一种常用的白平衡算法,它基于假设图像中的所有颜色的平均值应该相等。本攻略将介绍灰度世界算法的原理和实现方法,并提供两个示例说明。 灰度世界算法原理 灰度世界算法的原理非常简单。它假设图像中的所有颜色的平均值应该相等。因此,我们可…

    other 2023年5月9日
    00
  • 光电鼠标右键不灵该怎么拆解维修?

    针对“光电鼠标右键不灵该怎么拆解维修?”这个问题,我为您提供以下完整攻略: 步骤1:检查鼠标驱动和软件设置 首先,您需要检查一下鼠标的驱动和软件设置是否有问题。有时候驱动没有安装正确或设置不当也会导致鼠标功能失效。您可以通过以下步骤进行检查: 点击“开始”菜单,选择“控制面板”。 在控制面板中选择“硬件和声音”选项,再选择“设备和打印机”。 找到您的鼠标,右…

    other 2023年6月27日
    00
  • PHP spl_autoload_register实现自动加载研究

    PHP中自动加载是一个非常重要的功能,然而在开发过程中我们使用大量的类,而一个一个地包含这些类不仅繁琐而且效率低下。PHP提供了一种自动加载机制,可以优化我们的开发流程。其中PHP spl_autoload_register函数就是实现自动加载功能的核心,本文将详细讲解如何使用PHP spl_autoload_register实现自动加载功能,以下是详细攻略…

    other 2023年6月27日
    00
  • 聊聊Python代码中if __name__ == ‘__main__‘的作用是什么

    聊聊Python代码中if name == ‘main’的作用是什么 在Python中,if __name__ == ‘__main__’ 是一个常见的代码块,它在一个模块被直接执行时会被执行,而在该模块被导入时不会被执行。这个代码块的作用是为了区分模块是被直接执行还是被导入执行。 作用 当一个Python脚本被执行时,Python解释器会将该脚本作为主程序…

    other 2023年8月5日
    00
  • Win10正式版1511 Build 10586.965累积更新补丁KB4032693下载地址 32位/64位

    Win10正式版1511 Build 10586.965累积更新补丁KB4032693下载地址 32位/64位攻略 1. 确认系统版本和位数 首先,我们需要确认系统版本和位数。打开Windows 10操作系统,点击开始菜单,选择“设置”(齿轮图标),然后点击“系统”选项。在系统设置页面中,点击“关于”选项卡。在关于页面中,可以找到系统版本和位数的信息。 2.…

    other 2023年8月4日
    00
  • Windows中的批处理的常用符号介绍

    下面是Windows中的批处理的常用符号介绍的完整攻略。 批处理符号介绍 批处理文件是面向计算机的一个命令脚本,可以自动化完成某一系列操作。在编写批处理脚本时,需要掌握一些特殊符号来完成某些操作。 echo echo命令可以输出文本信息到屏幕上,语法如下: echo <字符串> 示例: 假设要输出“Hello World!”到屏幕上,可以使用以下…

    other 2023年6月26日
    00
  • 实现core文件自动生成配置文件的方法

    实现Core文件自动生成配置文件的方法有以下步骤: 1. 确认系统支持coredump 要生成Core文件,需要确认系统已经打开了生成Core文件的权限。可以通过以下方式查看: ulimit -a 如果core file size显示为0,则需要修改设置: ulimit -c unlimited 2. 确认系统生成了Core文件 当程序崩溃时,会生成Core…

    other 2023年6月25日
    00
  • sqlserverjoin介绍

    SQL Server Join 介绍 在本文中,我们将细致地介绍 SQL Server Join 的概念及其使用方法。Join 是 SQL Server 中最基础和常用的操作之一,能够将多个表的数据进行组合,并返回一个视图(Virtual Table),使其在实际应用中发挥重要的作用。 JOIN的类型 SQL Server 中的 JOIN 主要分为以下四种类…

    其他 2023年3月29日
    00
合作推广
合作推广
分享本页
返回顶部