iOS扫一扫功能开发

作者: 千煌89 | 来源:发表于2015-04-07 18:18 被阅读18427次

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

    初始化相机,扫描器

    - (void)setupCamera
    {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 耗时的操作
            // Device
            _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
            
            // Input
            _input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];
            
            // Output
            _output = [[AVCaptureMetadataOutput alloc]init];
            //    [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
            [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
            
            // Session
            _session = [[AVCaptureSession alloc]init];
            [_session setSessionPreset:AVCaptureSessionPresetHigh];
            if ([_session canAddInput:self.input])
            {
                [_session addInput:self.input];
            }
            
            if ([_session canAddOutput:self.output])
            {
                [_session addOutput:self.output];
            }
            
            // 条码类型 AVMetadataObjectTypeQRCode
            _output.metadataObjectTypes =@[AVMetadataObjectTypeQRCode];
            dispatch_async(dispatch_get_main_queue(), ^{
                // 更新界面
                // Preview
                _preview =[AVCaptureVideoPreviewLayer layerWithSession:self.session];
                _preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
                //    _preview.frame =CGRectMake(20,110,280,280);
                _preview.frame = self.view.bounds;
                [self.view.layer insertSublayer:self.preview atIndex:0];
                // Start
                [_session startRunning];
            });
        });
    }
    

    在viewWillAppear和viewWillDisappear里对session做优化。

    -(void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
        if (_session && ![_session isRunning]) {
            [_session startRunning];
        }
        timer = [NSTimer scheduledTimerWithTimeInterval:.02 target:self selector:@selector(animation1) userInfo:nil repeats:YES];
    }
    
    - (void)viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear:animated];
        [timer invalidate];
    }
    

    以上timer是个扫描动画的计时器,可以略过不看。

    处理扫描的结果

    - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
    {
        
        NSString *stringValue;
        
        if ([metadataObjects count] >0)
        {
            AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];
            stringValue = metadataObject.stringValue;
        }
        
        [_session stopRunning];
        [timer invalidate];
        NSLog(@"%@",stringValue);
        
    }
    

    用二维码扫描器扫自己的二维码

    NSString *url = [NSURL URLWithString:@"html/judgement.html" relativeToURL:[ZXApiClient sharedClient].baseURL].absoluteString;
        
        if ([stringValue hasPrefix:url]) {
            //如果扫出来的url是自己的域名开头的,那么做如下的处理。
        } 
    

    用二维码扫描器扫别人的二维码

    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:stringValue]];
    

    直接使用openUrl系统自带的浏览器打开url就行,或者自己写个内置的浏览器打开。

    用别人的扫描器扫自己的二维码

    首先将自己的二维码定义成http://www.xxx.com/xxxxx这样的自己域名的url。
    那么第三方的二维码扫出来后,会跳向这个网址。

    其次在服务器上部署这个页面,加入如下的代码

    <script language="javascript">
      if (navigator.userAgent.match(/(iPhone|iPod|iPad);?/i)) {
        var loadDateTime = new Date();
        window.setTimeout(function() {
          var timeOutDateTime = new Date();
          if (timeOutDateTime - loadDateTime < 5000) {
            window.location = "要跳转的页面URL";
          } else {
            window.close();
          }
        },
        25);
        window.location = " test:// ";
      } else if (navigator.userAgent.match(/android/i)) {
        var state = null;
        try {
          state = window.open("apps custom url schemes ", '_blank');
        } catch(e) {}
        if (state) {
          window.close();
        } else {
          window.location = "要跳转的页面URL";
        }
      }
    </script>
    

    这段代码是基于url schemes的原理,如果你的app里存在这个url schemes(例子里是test://),那么会立刻打开这个url,如果不存在,就会超过25毫秒,那么就指向另一个页面,一般是下载页。

    接着,在app的url schemes里设置,比如test

    Paste_Image.png

    这个时候,浏览器发出test://的请求的时候,就能立刻打开这个app了。

    最后,如果不满足于扫描二维码只能打开app,想对二维码里的内容做一些操作的话,可以:

    • 将二维码的内容定义成http://www.xxx.com/xxxxx?uid=xxx这样,当然后面的参数需要加密。
    • 在js代码里获取这个参数,并原封不动的附加在url schemes后面,如test://uid=xxx
    • 在appDelegate里加上如下代码。
     - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
    {
        if ([url.absoluteString hasPrefix:@"test://uid="]) {
            NSString *uid = [url.absoluteString substringFromIndex:11];
            NSLog(@"uid=%@",uid);
            //对uid进行操作
        } else {
            //其他的地方抛过来的url,比如微信
            return [WXApi handleOpenURL:url delegate:self];
        }
        return YES;
    }
    

    用别人的扫描器扫别人的二维码

    34ebbc5ccf91e9deffe7f8d1fead2675.png

    最后来张效果图

    2015-04-08 09_52_30.gif

    应许多同学要求,上个demo

    demo

    相关文章

      网友评论

      • 我想大声对你说:怎么demo运行报错呢
      • 流星载梦:请教一下,用二维码扫描器扫自己的二维码 [NSURL URLWithString:@"html/judgement.html" relativeToURL:[ZXApiClient sharedClient].baseURL].absoluteString; 这地方是什么意思,怎么用的还有后面这个[ZXApiClient sharedClient].baseURL].absoluteString
        千煌89:@流星载梦 这是自定义的url啊,单纯用来做判断的
      • LionNeo_Liu:微信扫一扫中当光线不足时显示点亮手电筒,这个用的是哪个挨批,请问大神
      • 某非著名程序员:good,学习下。
      • 乱尘:Good JB
      • 6239961ce796:写的不错,直接把damo里面的图扣下来用了
      • ac2c5e86bd8c:感谢分享:heart_eyes::heart_eyes:
      • ff4027bec949:还不错 收藏
      • rainbowboy:啊啊
      • NS西北风:楼主,能不能把demo贴出来。
      • b57503882b24:问一下 二维码扫描后怎么获取 二维码本身的 uRl 啊 ?????????
        千煌89:@b57503882b24 二维码的信息里只有一个字符串,这个字符串可以是url,你要判断哪个是你的二维码,得有一个参考值,比如uri = @"http://www.me.com&quot;,判断下[stringValue hasPrefix:uri].
        b57503882b24:@千煌89 stringValue 这个 就是扫描二维码之后 获取的信息 字段吧........
        我想问的是扫描二维码之后得到这个二维码的信息, 除了这个 是否还有别的字段,比如两个二维码, 一个是我自己app的,另一个是牛奶的,我想判断这两个二维码哪个是我的, 而不是通过扫描得到的结果字段获取, 二维码本身是否有个像网址似的 一个url
        千煌89:@b57503882b24 - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
        {

        NSString *stringValue;

        if ([metadataObjects count] >0)
        {
        AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];
        stringValue = metadataObject.stringValue;
        }

        [_session stopRunning];
        [timer invalidate];
        NSLog(@"%@",stringValue);

        }
        这个stringValue就是二维码本身的字符串,至于什么本身的uRl,我不知道你在说什么
      • WELCommand:不错 马一下
      • 花前月下:支持下。写的不错
      • 29a42b555c4e:二维码
      • 9913e661dff4:喜欢。
      • 煜寒了:@千煌89 嗯。 直接关闭也可以,看需求,呵呵
      • 千煌89:@ThinkerDown 我想起来了,这份代码,我扫描成功后会跳转,然后会关闭session
      • 千煌89:@ThinkerDown 恩,我之前也遇到了这个问题,修复之后忘了修改文章了
      • 煜寒了:楼主很详细,我也写过这个,这份代码在7.1系统上应该有问题,扫描的时候会扫描多次,建议加个判断,三年成功后就停掉它
      • Lonely__M:mark。。
      • _李布斯:版主,能集成个demo 学习学习吗?
      • __SanJi:请教一下,原生扫描支持从相册读取图片扫描吗?
      • 3f133293f9dd:嗯,不错!谢谢分享!

      本文标题:iOS扫一扫功能开发

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