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日

相关文章

  • vue项目中使用rem替换px的实现示例

    下面我来详细讲解一下在Vue项目中使用rem替换px的具体实现攻略。 什么是rem 如果你对rem的概念还比较陌生,那么简单来说,rem就是相对于根节点(html或body)设置的字体大小。也就是说,我们设置元素的长度、宽度、边框等样式属性时,直接使用rem就能够根据根节点设置的字体大小来进行自适应,达到了适配不同屏幕尺寸的效果。 实现步骤 接下来,我会详细…

    other 2023年6月27日
    00
  • 用ajax实现在单击事件下加载一个DIV层的脚本

    想要使用ajax实现在单击事件下加载一个DIV层的脚本,需要经过以下步骤: 1. HTML中创建需要加载的DIV层 首先,在HTML中创建一个需要加载的DIV层,可用以下代码实现: <div id="content"></div> 2. 定义单击事件 接下来,需要用JavaScript来定义单击事件,代码如下: c…

    other 2023年6月25日
    00
  • 猎豹免费wifi5.0下载 猎豹免费wifi5.0官方下载地址

    猎豹免费WiFi 5.0 下载攻略 猎豹免费WiFi是一款功能强大的免费WiFi管理工具,它可以帮助用户快速连接和管理WiFi网络。以下是猎豹免费WiFi 5.0的详细下载攻略,包括官方下载地址和两个示例说明。 步骤一:访问官方网站 首先,你需要访问猎豹免费WiFi的官方网站来获取最新版本的下载链接。你可以通过以下步骤访问官方网站: 打开你的浏览器,输入猎豹…

    other 2023年8月4日
    00
  • PHP登录验证功能示例【用户名、密码、验证码、数据库、已登陆验证、自动登录和注销登录等】

    以下是详细的PHP登录验证功能示例攻略: 1. 创建数据库 首先,在MySQL数据库中,创建一个名为“users”的表格,其中应包含以下列: id:主键,整型,自增长 username:用户名,字符串类型,长度为50 password:密码,字符串类型,长度为255 创建的SQL代码如下: CREATE TABLE `users` ( `id` int(11…

    other 2023年6月27日
    00
  • java-为什么我收到此错误’illegalstartoftype’?

    当然,我可以为您提供“Java-为什么我收到此错误’illegalstartoftype’?”的完整攻略,过程中包含两条示例说明。攻略如下: Java-为什么我收到此错误’illegalstartoftype’? 在Java编程中,当您在类的外部使用类的非静态成员时,您需要使用该类的实例来访问它们。如果您在类的外部使用类的静态成员,则可以直接使用类名访问它们…

    other 2023年5月9日
    00
  • Java中比较抽象类与接口的异同

    Java中的抽象类和接口是两种非常重要的抽象概念,它们可以用来定义一组规范,使得子类可以基于这个规范去实现自己的特殊行为。但是,虽然它们都具有类似的特性,但是它们也存在着很多本质的区别。下面,我们将具体讨论Java中比较抽象类与接口的异同。 相同点 都是Java中的抽象概念,不能直接被实例化。 都可以被子类继承或实现,其子类必须要实现其抽象方法或者重写其具体…

    other 2023年6月26日
    00
  • web前端助手(fehelper)

    Web前端助手(fehelper)完整攻略 Web前端助手(fehelper)是一款Chrome浏览器插件,它提供了一系列实用前端开发具,包括页面元素查看、CSS样式查看、JS调试、JSON格式化、二维码生成等功能。本攻略将详细绍Web前端助手的安装、配置和使用方法,包括基本概念、安装配置和示例说明。 基本概念 Web前端助手(fehelper)是一款Chr…

    other 2023年5月6日
    00
  • jquery 验证用户名是否重复代码实例

    使用jQuery验证用户名是否重复是一件常见的任务,一般需要使用AJAX异步请求后端API接口来查询数据库中是否已经存在对应的用户名。下面将对此过程进行完整的讲解。 第一步:前端页面编写 首先我们需要在前端页面中添加一个文本框用于用户输入用户名,并添加一个按钮用于触发验证,代码如下: <label for="username"&gt…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部