序言

前面我们已经调到过怎么制作二维码,在我们能够生成二维码之后,如何对二维码进行扫描呢?

在iOS7之前,大部分应用中使用的二维码扫描是第三方的扫描框架,例如ZXing或者ZBar。使用时集成麻烦,出错也不方便调试。在iOS7之后,苹果自身提供了二维码的扫描功能,从效率上来说,原生的二维码远高于这些第三方框架。本文讲解如何使用原生框架实现二维码扫描功能,并且进行扫描后的项目跳转。


扫描相关类

二维码扫描需要获取摄像头并读取照片信息,因此我们需要导入系统的AVFoundation框架,创建视频会话。我们需要用到一下几个类:

AVCaptureSession 会话对象。此类作为硬件设备输入输出信息的桥梁,承担实时获取设备数据的责任
AVCaptureDeviceInput 设备输入类。这个类用来表示输入数据的硬件设备,配置抽象设备的port
AVCaptureMetadataOutput 输出类。这个支持二维码、条形码等图像数据的识别
AVCaptureVideoPreviewLayer 图层类。用来快速呈现摄像头获取的原始数据
二维码扫描功能的实现步骤是创建好会话对象,用来获取从硬件设备输入的数据,并实时显示在界面上。在扫描到相应图像数据的时候,通过AVCaptureVideoPreviewLayer类型进行返回


应用跳转

在使用第三方登陆、分享sdk的时候,我们的项目会在本机安装有目标平台的应用的情况下进行应用跳转,并且传递信息过去。这在沙盒机制下的iOS应用而言,理应是不符合规则的。但是,iOS SDK给我们提供了一个叫做url scheme的机制来实现这个功能。

url scheme让我们可以像使用Safari打开网页的方式跳转到其他应用中,并使用类似网络请求的GET请求的参数拼凑方式来在不同应用之间传递数据。

使用url scheme的第一步是在项目的info.plist文件中添加新row,命名为URL types

展开新增的字典,我们修改其中的URL Identifier以及新增加一个字段

URL Schemes。
Identifier用来跳转后,让跳转应用识别从哪里跳转过来的,我们可以设置为bundleID反转,来确保其特殊性。
URL Schemes是一个数组,我们将在这个数组里面自定义自己的url schemes,这里我们填写应用名。最终效果如下:

接着,我们就可以在其他应用中通过openURL:方法打开我们的app。


二维码扫描

二维码扫描的步骤:
1、创建设备会话对象,用来设置设备数据输入
2、获取摄像头,并且将摄像头对象加入当前会话中
3、实时获取摄像头原始数据显示在屏幕上
4、扫描到二维码/条形码数据,通过协议方法回调

会话对象AVCaptureSession的创建_session = [AVCaptureSession new];[_session setSessionPreset: AVCaptureSessionPresetHigh];    //高质量采集
  [self setupIODevice];
setupIODevice方法中懒加载方式创建输入对象和输出对象,注意必须在输出数据对象加入到当前会话后才能设置识别的数据格式。这里设置为扫描二维码以及条形码[_session addInput: self.input];[_session addOutput: self.output];_output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];
创建AVCaptureMetadataOutput设置好扫描成功回调代理以及回调线程_output = [AVCaptureMetadataOutput new];[_output setMetadataObjectsDelegate: self queue: dispatch_get_main_queue()];
创建AVCaptureDeviceInput输入设备为手机摄像头AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo];_input = [AVCaptureDeviceInput deviceInputWithDevice: device error: nil];
创建AVCaptureVideoPreviewLayer对象来实时获取摄像头图像,我们需要调用[self.view addSubview: self.scanView]把摄像头获取的图像实时展示在屏幕上_scanView = [AVCaptureVideoPreviewLayer layerWithSession: self.session];_scanView.videoGravity = AVLayerVideoGravityResizeAspectFill;_scanView.frame = self.bounds;
实现captureOutput: didOutputMetadataObjects: fromConnection:来获取扫描得到的数据。回调参数metadataObjects中存放了扫描结果,我们需要先判断这个数组的数据个数不为0再执行下面的代码:[self stop];AVMetadataMachineReadableCodeObject * metadataObject = metadataObjects[0];if ([self.delegate respondsToSelector: @selector(scanView:codeInfo:)]) {[self.delegate scanView: self codeInfo: metadataObject.stringValue];[self removeFromSuperview];} else {[[NSNotificationCenter defaultCenter] postNotificationName: SuccessScanQRCodeNotification object: self userInfo: @{ ScanQRCodeMessageKey: metadataObject.stringValue }];


读取二维码信息进行应用跳转

首先要说明的是,二维码并非一定要存储应用的url scheme。例如公众号的二维码,虽然不知道是怎样的数据存储,但肯定不是应用跳转。可以给自己的应用指定一个二维码数据规则,例如支付宝付款扫描是读取商品的ID、价格等信息,然后进行页面跳转付款。
这里我们使用上面设置的url scheme,我们通过制作二维码方法来定制一个存储应用跳转信息的二维码,通过下面的代理创建一个存储url scheme(使用url scheme的时候要注意在后面加上://后才能使用openURL进行跳转)的二维码,这一步应该放到模拟器上面生成

- (IBAction)createBarcode:(id)sender
{UIImage image = [UIImage imageOfQRFromURL: @"DrawLosts://" codeSize:     160.f red: 123 green: 189 blue: 229 insertImage: nil];CGSize size = image.size;UIImageView imageView = [[UIImageView alloc] initWithFrame: ((CGRect)    {(CGPointZero), (size)})];imageView.center = self.view.center;imageView.image = image;[self.view addSubview: imageView];
}

创建二维码扫描控制器,然后对我们生成的二维码进行扫描(这一步要在真机上面完成,上面url scheme的应用应当通过xcode安装在手机上,才能完成跳转)

ScanCodeController * scanCodeController = [ScanCodeController scanCodeController];
scanCodeController.scanDelegate = self;
[self.navigationController pushViewController: scanCodeController animated: YES];

扫描成功后判断是否可以打开跳转,如果你的应用有一套二维码数据存储的规则,那么在不能跳转的时候应该按照这套规则解析数据。这里我直接在无法跳转的情况下显示警告框告诉用户无法解析二维码:

NSURL * url = [NSURL URLWithString: codeInfo];
if ([[UIApplication sharedApplication] canOpenURL: url]) {[[UIApplication sharedApplication] openURL: url];
} else {UIAlertView * alertView = [[UIAlertView alloc] initWithTitle: @"警告" message:    [NSString stringWithFormat: @"%@:%@", @"无法解析的二维码", codeInfo] delegate: nil cancelButtonTitle: @"确定" otherButtonTitles: nil];[alertView show];
}

按照上面的步骤进行的话,那么在你扫完二维码之后,你的手机就会跳转到刚才设置url scheme的应用中。


扫描优化

上面已经完成了二维码的扫描功能实现,但是现在你会发现我们在使用上面代码进行扫描的时候,整个屏幕都是扫描范围,这样会影响扫描的准确性以及我们调整扫描范围的难度。
苹果提供了一种方式让我们规定扫描范围:在AVCaptureMetadataOutput中有一个叫做rectOfInterest的CGRect类型属性,这个属性用来限制扫描范围。
这个属性的每一个值取值范围在0~1之间,代表的是对应轴上的比例大小。最开始我以为这个是以左上角为原点,后来设置为CGRectMake(0.3, 0.35, 0.4, 0.3)发现和预期的不一样,因为这个属性是以屏幕右上角为坐标原点,并且宽高的顺序要对换过来

如图所示,由于坐标系的不同,原本CGRectMake(0.3, 0.35, 0.4, 0.3)到了新坐标系中就变成了CGRectMake(0.35, 0.3, 0.3, 0.4)。那么大家设置成新的扫描范围之后,重新运行扫描程序,看看效果——然而,我们发现并不能扫描成功,这是因为这个扫描区域不仅仅是坐标系原点发生了改变。如下图所示

按照上面CGRect的设置,我是想要把扫描范围控制在屏幕x轴上面0.3-0.7,y轴上0.35-0.65之间的范围。但是在这个属性中,width和height分别表示的是在rectOfInterest坐标中扫描矩形右下角的坐标点位置。因此,这个扫描范围应该是CGRectMake(0.35, 0.3, 0.65, 0.7)。除了设置好扫描范围之内,我们还可以仿照微信的扫描,给非扫描范围加上一层半透明的黑色layer


应用传值

前面说过,url scheme不仅仅支持应用跳转,它还支持使用类似get请求的方式在应用间传值。上面跳转的url scheme是DrawLosts://,那么类似get请求,我们在这个字符串后面加上一个?表示区分开参数和应用id,使用&分隔不同参数,然后后面按照字段名=属性值的方式拼凑链接。
比如,假设这是一个即时通讯app,那么我可以制定这样的一个跳转参数规则:

method 表示操作类型
userId 用户id
title 分享标题
message 分享消息
link_url 分享链接

那么,如果传入的是

DrawLosts://?method=addFriends&userId=10086
这可能代表的是扫描后添加id为10086的新好友。

这些都是我们自己的应用可以制定的规则,如果有兴趣,可以新浪微博开放平台或者腾讯开放平台,他们的文档中应该有url scheme的传值标准。

说完了通过url scheme传入参数后,怎么把这些参数取出来呢?AppDelegate中提供了application:openURL: sourceApplication: annotation:方法让我们可以取出传入的值。
在我们通过url scheme跳转到本应用的时候,这个方法就会被系统调用。其中,有两个重要的参数需要我们知道

sourceApplication 这个字符串保存了跳转方app的url Identifier,就是上文中除了url scheme以外的另一个字段
url 这个链接中存储了跳转的url scheme以及参数列表,我们通过[url scheme]方法获取前者;用[url query]方法获取?之后的参数列表,然后使用字符串的分隔方法把这些数据读取出来

单纯的二维码数据并没有过于强大的功能,但结合了url scheme的跳转机制后,二维码能够帮助我们的应用获得更加强大的能力,使得我们的应用之间有了更多联系。

转载于:https://www.cnblogs.com/gongyuhonglou/p/5570417.html

iOS - 二维码扫描和应用跳转相关推荐

  1. iOS开发-二维码扫描和应用跳转

    iOS开发-二维码扫描和应用跳转   序言 前面我们已经调到过怎么制作二维码,在我们能够生成二维码之后,如何对二维码进行扫描呢? 在iOS7之前,大部分应用中使用的二维码扫描是第三方的扫描框架,例如Z ...

  2. ios客户端学习-二维码扫描和应用跳转

    转载至链接:http://sindrilin.com/ios-dev/2015/11/01/二维码扫描和应用跳转.html 序言 在iOS7之前,大部分应用中使用的二维码扫描是第三方的扫描框架,例如Z ...

  3. 二维码扫描和应用跳转

    转载自: http://sindrilin.com/ios-dev/2015/11/01/二维码扫描和应用跳转.html 前面我们已经调到过怎么制作二维码,在我们能够生成二维码之后,如何对二维码进行扫 ...

  4. iOS二维码扫描/识别

    一直以为二维码功能比较简单,  从来没有放在心上过,  由于公司项目需要这个功能,  也算是第一次真正去做二维码的东西.  从网上看别人的博客很多都是写的比较碎片, 没有一个能做的比较完整的,  今天 ...

  5. IOS二维码扫描功能的实现

    之前很多二维码扫描都是基于zxing做的,但是zxing用起来真的很麻烦,又一直不更新.随着iOS6退出历史舞台,终于可以使用iOS7以后,用系统的AVFoundation做的二维码扫描器了. 初始化 ...

  6. ios二维码扫描插件,适配当前主流扫描软件,自定义扫描界面。

            二维码介绍: 二维码(QR(Quick Response)code),又称二维条码,最早起源于日本. 它是用特定的几何图形按一定规律在平面(二维方向)上分布的黑白相间的图形,是所有信息 ...

  7. iOS 二维码扫描(zxing)的使用教程

    ZXing(Github镜像地址)是一个开源的条码生成和扫描库(开源协议为Apache2.0).它不但支持众多的条码格式,而且有各种语言的实现版本,它支持的语言包括:Java, C++, C#, Ob ...

  8. iOS 二维码扫描和成像,成像带小图标 自定义色值

    工具下载:http://download.csdn.net/detail/wsk_123_123/7177635 代码: // // YYViewController.h // Dm // // Cr ...

  9. 在Vue中生成二维码扫描在手机上跳转页面

    使用方法: 安装vue-qr npm install vue-qr --save 在components新建一个vue组件,eg:vueQr.vue (以下为组件完整代码) <template& ...

最新文章

  1. Hyperledger Indy 理解
  2. VMware虚拟机下安装Ubuntu16.04镜像完整教程
  3. 代码阅读 | 孪生网络目标跟踪的尺度(Scale)计算 (In ATOM)
  4. win10电脑插入U盘不显示U盘盘符怎么办?
  5. HihoCoder - 1829 Tomb Raider (暴力+最长上升子序列)
  6. Python: pandas中ix的详细讲解
  7. 2022年医院三基考试肿瘤相关训练题及答案
  8. java stl 模型 切片_使用 Materialise magics 对 STL文件进行切片
  9. stm32f4实现s6d1121+xtp2046触摸屏功能
  10. Python dict字典基本操作
  11. 后缀为whl的文件是什么?如何安装whl文件?学习一下(22)
  12. 人大金仓KingbaseES大小写敏感性专题
  13. 误提交了target目下的文件怎么删除?
  14. org.eclipse.wst.validation has been removed
  15. Android 圆形图片 CircleImageView(Xfermode方式)
  16. src下创建java文件_Eclipse下maven项目创建src/main/java 源文件夹报错文件文件已存在问题...
  17. 复现腾讯表格识别解析| 鹅厂技术
  18. MySQL数据库函数
  19. Altium Designer中多图纸电路原理图的设计
  20. 李开复教你如何发现自己的兴趣爱好

热门文章

  1. vue可填写表格_VUE写一个简单的表格实例
  2. intel和amd的cpu核心详细介绍
  3. Idea maven无法下载jar问题解决
  4. 【视频编码】软解与硬解
  5. C# List集合查找删除指定数据
  6. 【c++ primer, 5e】访问控制与封装
  7. 5G概念被热炒,运营商吃相不要太难看 1
  8. imatest软件的学习 及使用
  9. 【5G NR】无线承载SRB和DRB
  10. ESXI虚拟机下直通外部USB硬盘给黑群晖当硬盘