美文网首页iOS常用
iOS扫描二维码

iOS扫描二维码

作者: anny_4243 | 来源:发表于2021-07-12 16:00 被阅读0次

    二维码在App中的使用越来越广泛,如支付软件用二维码确定支付信息,社交软件用二维码添加联系人,下载页面用二维码链接到App Store下载链接等。二维码能存储汉字、数字、字母和图片等信息,因此二维码的应用领域很广泛。

    二维码(2-dimensional bar code)是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的技术。在代码编制上巧妙地利用构成计算机内部逻辑基础的“0”“1”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图像输入设备或光电扫描设备自动识读以实现信息自动处理。

    常用的二维码是QR码(QR Code),是一种矩阵二维码符号码。它的示例和结构如图4-13所示。

    图4-13 QR码示例和结构

    扫描二维码已成为实际开发中的常用功能,接下来就围绕如何扫描二维码进行详细的分步骤介绍,具体如下。

    1. 导入头文件
    由于扫描二维码的相关类都包含在AVFoundation框架中,所以要导入<AVFoundation/AVFoundation.h>头文件,具体代码如下:

    #import <AVFoundation/AVFoundation.h>
    

    2.创建会话
    由于iOS系统用一个会话对象管理扫描过程,所以在扫描时第1步是创建会话对象。会话使用AVCaptureSession类。创建会话之前首先要定义一个属性保存会话对象,代码如下:

    @property (nonatomic, strong) AVCaptureSession *session;
    

    然后创建会话对象,并赋值给这个属性,代码如下:

    self.session = [[AVCaptureSession alloc]init];
    

    3. 创建输入设备

    要扫描二维码,必须用到摄像头,也就是输入设备。输入设备要关联到会话,指定扫描会话所使用的输入设备。输入设备用AVCaptureDeviceInput类表示,具体代码如例4-11所示。

    【例4-11】ViewController.m文件中创建输入对象

    //创建一个普通设备
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    //根据普通设备创建一个输入设备
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
    //将输入设备关联到会话
    if ([self.session canAddInput:input]) {
        [self.session addInput:input];
    }
    

    在例4-11中,首先创建了一个普通设备,并指定普通设备的类型为视频输入,创建出的普通设备一般是后置摄像头。然后根据这个普通设备创建输入设备。最后判断该输入设备是否能成功关联到会话,如果可以,则执行关联。

    4. 创建输出对象

    在输入设备扫描到二维码以后,输出对象负责识别二维码包含的信息,并将识别到的信息传递出来。输出对象使用AVCaptureMetadataOutput类表示。示例代码如例4-12所示。

    【例4-12】ViewController.m文件中创建输出对象

    //创建一个输出对象
    AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc]init];
    //输出对象关联到会话
    if ([self.session canAddOutput:output]) {
        [self.session addOutput:output];
    }
    //设置元数据类型,是QR二维码
    output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode];
    //设置代理,得到解析结果
    [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    

    例4-12的代码中,第2行代码创建了输出对象,第4~6行代码判断该输出对象是否可以关联到会话,如何可以,就执行关联。第8行代码设置输出对象的元数据类型为AVMetadataObjectTypeQRCode,也就是二维码类型。第10行代码设置输出对象的代理,以后由代理来处理输出对象识别到的信息。

    5. 创建显示扫描的层

    在摄像头扫描时,需要创建一个特殊的CALayer来显示摄像头拍摄到的视频内容,这个类是CALayer的子类,叫做AVCaptureVideoPreviewLayer。要创建这个AVCaptureVideoPreviewLayer对象,首先要定义一个属性保存它,示例代码如下。

    @property (nonatomic, strong) AVCaptureVideoPreviewLayer *preLayer;
    

    然后创建这个层对象,并赋值给该属性,示例代码如例4-13所示。

    【例4-13】ViewController.m文件中创建显示扫描的层

    //创建一个特殊的层
    self.preLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:self.session];
    //设置尺寸并添加到视图树
    self.preLayer.frame = self.view.bounds;
    [self.view.layer addSublayer:self.preLayer];
    

    在例4-13的代码中,首先创建了一个层对象,然后设置层的尺寸与控制器视图的尺寸相同,最后将扫描层添加到控制器的视图树中。

    6. 开启会话

    到这一步,会话已经准备好了,使用会话对象的startRunning方法开启会话,则摄像头被打开,扫描开始。具体代码如下:

    [self.session startRunning];
    
    1. 获取二维码信息
      识别到的二维码信息由输出对象交给代理对象处理。AVCaptureMetadataOutput类规定一个协议,叫做AVCaptureMetadataOutputObjectsDelegate,该协议只有一个方法,该方法的参数metadataObjects里就包含了识别到的二维码信息。该方法定义如下:
    -(void)captureOutput:(AVCaptureOutput *)output didOutputMetadataObjects:(NSArray<__kindof AVMetadataObject *> *)metadataObjects fromConnection:(AVCaptureConnection *)connection
    

    在创建输出对象时已将控制器设置为输出对象的代理。控制器要成为它的代理,首先必须遵守AVCaptureMetadataOutputObjectsDelegate协议,示例代码如下:

    @interface ViewController ()<AVCaptureMetadataOutputObjectsDelegate>
    

    然后要实现代理方法,示例代码如例4-14所示。

    【例4-14】ViewController.m文件中实现代理方法

    -(void)captureOutput:(AVCaptureOutput *)output didOutputMetadataObjects:(NSArray<__kindof AVMetadataObject *> *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
        //停止会话
        [self.session stopRunning];
        //移除显示扫描层
        [self.preLayer removeFromSuperlayer];
        if (metadataObjects.count > 0) {
            AVMetadataMachineReadableCodeObject *object = [metadataObjects firstObject];
            NSLog(@"%@",object.stringValue);
        }
    }
    

    在例4-14所示的代理方法中,停止会话,即停止扫描。然后将创建的显示扫描的层从控制器的视图树上移除。首先判断metadataObjects中是否有对象,如果有则取出该对象,并将对象的stringValue字符串值打印到控制器。

    编写完代码,执行程序,就可以在控制台打印出识别到的二维码信息了。

    摘自《iOS开发项目化经典教程》

    相关文章

      网友评论

        本文标题:iOS扫描二维码

        本文链接:https://www.haomeiwen.com/subject/pdirpltx.html