Create QRScanner.swift file

  1. //
  2. // QRScanner.swift
  3. // NativeQR
  4. //
  5. // Created by Harvey on 2017/10/24.
  6. // Copyright © 2017年 Harvey. All rights reserved.
  7. //
  8. import Foundation
  9. import AVFoundation
  10. import UIKit
  11. class QRScanner: NSObject {
  12. static let shared = QRScanner()
  13. private let captureSession = AVCaptureSession()
  14. private let videoPreviewLayer = AVCaptureVideoPreviewLayer()
  15. private var handleCompleted: ((String) -> ())? = nil
  16. private override init() {
  17. super.init()
  18. AVCaptureDevice.requestAccess(for: AVMediaType.video) { (isSuccess) in
  19. if isSuccess {
  20. self.prepare()
  21. }else {
  22. print("无权访问摄像机")
  23. }
  24. }
  25. }
  26. private func prepare() {
  27. guard let device = AVCaptureDevice.default(for: .video) else {
  28. print("获取摄像设备发生错误")
  29. return
  30. }
  31. guard let deviceInput = try? AVCaptureDeviceInput(device: device) else {
  32. print("创建设备输入流发生错误")
  33. return
  34. }
  35. // 创建数据输出流
  36. let metadataOutput = AVCaptureMetadataOutput()
  37. metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
  38. // 创建设备输出流
  39. let videoDataOutput = AVCaptureVideoDataOutput()
  40. videoDataOutput.setSampleBufferDelegate(self, queue: DispatchQueue.main)
  41. // 会话采集率: AVCaptureSessionPresetHigh
  42. captureSession.sessionPreset = .high
  43. // 添加数据输出流到会话对象
  44. captureSession.addOutput(metadataOutput)
  45. // 添加设备输出流到会话对象
  46. captureSession.addOutput(videoDataOutput)
  47. // 添加设备输入流到会话对象
  48. captureSession.addInput(deviceInput)
  49. // 设置数据输出类型
  50. metadataOutput.metadataObjectTypes = [
  51. .qr, // 二维码
  52. .ean13, // 条形码
  53. .ean8, // 条形码
  54. .code128 // 条形码
  55. ]
  56. videoPreviewLayer.session = captureSession
  57. videoPreviewLayer.videoGravity = .resizeAspectFill
  58. }
  59. func scan(design: @escaping (_ previewLayer: CALayer)->()) -> Self {
  60. design(videoPreviewLayer)
  61. startRunning()
  62. return self
  63. }
  64. func completed(aCompleted: @escaping (_ value: String)->()) {
  65. self.handleCompleted = aCompleted
  66. }
  67. func startRunning() {
  68. captureSession.startRunning()
  69. }
  70. func stopRunning() {
  71. captureSession.stopRunning()
  72. }
  73. }
  74. extension QRScanner: AVCaptureMetadataOutputObjectsDelegate {
  75. func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
  76. guard metadataObjects.count>0 else{
  77. return
  78. }
  79. stopRunning()
  80. guard let stringValue = metadataObjects.first!.value(forKey: "stringValue") as? String else {
  81. return
  82. }
  83. handleCompleted?(stringValue)
  84. }
  85. }
  86. extension QRScanner: AVCaptureVideoDataOutputSampleBufferDelegate {
  87. func captureOutput(_ output: AVCaptureOutput, didDrop sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
  88. }
  89. }

使用示例

  1. override func viewDidAppear(_ animated: Bool) {
  2. super.viewDidAppear(animated)
  3. QRScanner.shared
  4. .scan { (previewLayer) in
  5. /// 设置preview的frame
  6. let width = UIScreen.main.bounds.size.width - 100
  7. previewLayer.frame = CGRect(x: 50, y: 100, width: width, height: width)
  8. self.view.layer.insertSublayer(previewLayer, at: 0)
  9. // 你的扫描动画代码
  10. // ......
  11. // ......
  12. }
  13. .completed { (qrValue) in // 处理二维码
  14. print(qrValue)
  15. // 结束你的扫描动画代码
  16. // ......
  17. // ......
  18. }
  19. }

代码及示例下载(有实现生成二维码)

前往

iOS 原生库(AVFoundation)实现二维码扫描,封装的工具类,不依赖第三方库,可高度自定义扫描动画及界面(Swift 4.0)的更多相关文章

  1. iOS - 原生的CIFilter生成二维码和条形码

    使用CIFilter可以不引入任何第三方库,就可以生成想要的二维码和条形码,今天简单的介绍一下使用CIFilter生成二维码和条形码.系统CIFilter生成的二维码和条形码的大小有时并不能满足需求, ...

  2. iOS 原生实现生成二维码(CoreImage)工具类,不依赖第三方库,可自定义背景颜色,添加logo(Swift 4.0)

    import Foundation import CoreImage import UIKit extension UIColor { var coreImageColor: CIColor { re ...

  3. java生成二维码并融合模板工具类

    二维码融合模板 二维码融合图片 import java.awt.AlphaComposite; import java.awt.Graphics2D; import java.awt.Image; i ...

  4. iOS使用AVFoundation实现二维码扫描(ios7以上)——转载

    关于二维码扫描有不少优秀第三方库: ZBar SDK 里面有详细的文档,相应介绍也非常多,如:http://rdcworld-iphone.blogspot.in/2013/03/how-to-use ...

  5. iOS使用AVFoundation实现二维码扫描

    原文:http://strivingboy.github.io/blog/2014/11/08/scan-qrcode/ 关于二维码扫描有不少优秀第三方库如: ZBar SDK 里面有详细的文档,相应 ...

  6. 【转】 iOS使用AVFoundation实现二维码扫描

    原文:http://strivingboy.github.io/blog/2014/11/08/scan-qrcode/ 关于二维码扫描有不少优秀第三方库如: ZBar SDK 里面有详细的文档,相应 ...

  7. iOS开发——高级技术&生成二维码

      生成二维码 因为项目里需要新增个功能,该功能用到了二维码技术.于是我便查阅了资料,先学习了二维码的生成. 我们使用libqrencode库来生成二维码.下载地址http://download.cs ...

  8. 使用Python的库qrcode生成二维码

    现在有很多二维码的生成工具,在线的,或者安装的软件,都可以进行生成二维码.今天我用Python的qrcode库生成二维码.需要预先安装  Image 库 安装 用pip安装 # pip install ...

  9. PHP 使用GD库合成带二维码的海报步骤以及源码实现

    PHP 使用GD库合成带二维码的海报步骤以及源码实现 在做微信项目开发过程中,经常会遇到图片合成的问题,比如将用户的二维码合成到宣传海报中,那么,遇到这种情况,利用PHP的GD库也是很容易实现的,实现 ...

随机推荐

  1. AVFoundation Programming Guide(官方文档翻译4)Editing - 编辑

    新博客:完整版 - AVFoundation Programming Guide 分章节版:- 第1章:About AVFoundation - AVFoundation概述- 第2章:Using A ...

  2. 第二类Stirling数推导

  3. java中的URLEncoder和URLDecoder类;中文在地址栏中的处理

    [IT168 技术文档] /* 网页中的表单使用POST方法提交时,数据内容的类型是 application/x-www-form-urlencoded,这种类型会: 1.字符"a" ...

  4. fiddler 针对单个接口打断点

    在命令行输入相关指令: 以慕课网为例: 请求前设置断点:bpu 实例: bpu https://www.imooc.com/index/getstarlist 请求 https://www.imooc ...

  5. phaser2->3:来个打地鼠试水

    本文中phaser具体版本 phaser2:2.8.1 phaser3:3.17.0 一.实现效果二.实现细节三.项目总结四.参考文档 一.实现效果 源码地址(phaser2&phaser3) ...

  6. 读书笔记——《在线》

    * 2017年10月24日 星期二 晴* ## "在线"是未来世界发展的关键.一个事物是不是符合未来发展的趋势,就是要看它是否在线. 插图 **在线** 正文 作者是王坚,阿里巴巴 ...

  7. yii框架通过控制台命令创建定时任务

    假设Yii项目路径为 /home/apps 1. 创建文件 /home/apps/web/protected/commands/console.php $yii = '/home/apps/frame ...

  8. 事务Transaction

    目录 为什么写这系列的文章 事务概念 ACID 并发事务导致的问题 脏读(Dirty Read) 非重复读(Nonrepeatable Read) 幻读(Phantom Reads) 丢失修改(Los ...

  9. redis BLPOP

    一.需求 redis中保存了需要download的image url,存储格式为列表. 我需要从列表中获取数据,将图片下载保存到本地. 列表中的数据是一直增加的. 二.实现 使用redis BLPOP ...

  10. 基于layPage分页插件浅析两种分页方式

    最近在开发过程中经常用到分页,今天挤出些时间来捋一捋自己的经验 在web开发中,一般显示数据列表页时,我们会用到分页控件来显示数据.采用分页一般基于两种不同的需求,一种是数据量不算很大,但是在页面展示 ...