zoukankan      html  css  js  c++  java
  • ios二维码扫描插件,适配当前主流扫描软件,自定义扫描界面。

              

    二维码介绍:

    二维码(QR(Quick Response)code),又称二维条码,最早起源于日本。

    它是用特定的几何图形按一定规律在平面(二维方向)上分布的黑白相间的图形,是所有信息数据的一把钥匙。

    二维码是一种比一维码更高级的条码格式。一维码只能在一个方向(一般是水平方向)上表达信息,

    而二维码在水平和垂直方向都可以存储信息。一维码只能由数字和字母组成,而二维码能存储汉字、数字和图片等信息,

    因此二维码的应用领域要广得多。

    二维码需求:

    开发一款二维码扫描插件,具有扫描大众二维码的能力,能够识别二维码当中包含的网页链接以及文本信息。对网页链接跳转safari浏览器(但是对自己公司的连接要求在app内部内置浏览器)。对扫描的内容弹出提示框。并且让别的app扫描我们自己的二维码的时候要跳转到appstore下载。

    需求确认:

    二维码算法自己写?不现实。开发周期太长,那就使用第三方那个库QR(Quick Response)code  ZBarSDK,读取信息的时候首先应该判断是不是网页连接,考虑用正则表达式对扫描的结果进行过滤。对于内置浏览器使用webview控件。弹出提示框使用UIAlertView太麻烦,而且不好用,所以采用开源第三方库BlockAlertActionSheet,BlockAlertActionSheet使用block做的一款具有提示功能类似UIAlertView  UIActionSheet等控件。很强大,很实用。

    二维码开发:

    首先在github上下载ZBar SDK

    地址https://github.com/bmorton/ZBarSDK

    下载BlockAlertActionSheet,

    新建一个test工程。在Main》storyboard上拖放一个button点击button开始扫描。

    为button连接插座事件。

    - (IBAction)btnClicked:(id)sender{

    }

    将ZBarSDK包含在项目工程当中。添加库:QuartzCore.framework ,CoreVideo.framework ,CoreMedia.framework,libiconv.dylib,CoreGraphics.framework。

    将BlockAlertActionSheet包含在项目工程当中

    在 WSQViewController.h中引入头文件。

    #import "ZBarSDK.h"

    #import "BlockAlertView.h"

    遵循协议 ZBarReaderDelegate,

    #pragma mark - ZBarReaderDelegate<UIImagePickerControllerDelegate>

    - (void) readerControllerDidFailToRead: (ZBarReaderController*) reader

        withRetry: (BOOL) retry

        {

        }

        

        //二维码

    - (void) imagePickerController: (UIImagePickerController*) reader

        didFinishPickingMediaWithInfo: (NSDictionary*) info

        {

      

    }

    定义实例变量:

    ZBarReaderViewController *reader;

    UIView* line; //二维码扫描线。

    BOOL isBottom;

    NSTimer* lineTimer;//二维码扫描线计时器。

    自定义二维码扫描界面,(想法是这样的,先把reader原来的界面全部清空,然后自定义界面,因为ZBarSDK是分装好的静态库,)

    -(void)setOverlayStyle:(ZBarReaderViewController *)reader_{

    for (UIView *temp in [reader_.view subviews]){

    for (UIButton* btn in [temp subviews]) {

    if ([btn isKindOfClass:[UIButton class]]) {

    [btn removeFromSuperview];

    }

    }

    //去掉toolbar

    for (UIToolbar* tool in [temp subviews]) {

    if ([tool isKindOfClass:[UIToolbar class]]) {

    [tool setHidden:YES];

    [tool removeFromSuperview];

    }

    }

    isBottom = NO;

    //扫描线

    line = [[UIView alloc] initWithFrame:CGRectMake(40, 105, 240, 2)];

    line.backgroundColor = [UIColor greenColor];

    [reader_.view addSubview:line];

    lineTimer = [NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector:@selector(moveLine) userInfo:nil repeats:YES];

    [lineTimer fire];

    UIImage *scanningBg = [UIImage imageNamed:@"scanning-568h.png"];

    CGSize size  = [UIScreen mainScreen].bounds.size;

    UIImageView *scanningView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];

    scanningView.image = scanningBg;

    [reader_.view addSubview:scanningView];

    //用于取消操作的button

    UIButton *cancelButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];

    UIImage *bimage = [UIImage imageNamed:@"yellowButton.png"];

    //[cancelButton setBackgroundImage:bimage forState:UIControlStateDisabled];

    [cancelButton setBackgroundColor:[UIColor whiteColor]];

    [cancelButton setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];

    [cancelButton setFrame:CGRectMake(20, size.height - 84, 280, 40)];

    [cancelButton setTitle:@"取消" forState:UIControlStateNormal];

    [cancelButton.titleLabel setFont:[UIFont boldSystemFontOfSize:20]];

    [cancelButton addTarget:self action:@selector(dismissOverlayView:)forControlEvents:UIControlEventTouchUpInside];

    [reader_.view addSubview:cancelButton];

    }

    }

    //屏幕移动扫描线。

    -(void)moveLine{

    CGRect lineFrame = line.frame;

    CGFloat y = lineFrame.origin.y;

    if (!isBottom) {

    isBottom = YES;

    y=y+245.0;

    lineFrame.origin.y = y;

    [UIView animateWithDuration:1.5 animations:^{

    line.frame = lineFrame;

    }];

    }else if(isBottom){

    isBottom = NO;

    y = y -245;

    lineFrame.origin.y = y;

    [UIView animateWithDuration:1.5 animations:^{

    line.frame = lineFrame;

    }];

    }

    }

    // 点击cancel  button事件

    - (void)dismissOverlayView:(id)sender{

    [lineTimer invalidate];

    [reader dismissModalViewControllerAnimated:YES];

    }

    接下来在viewdidload中初始化 reader

    - (void)viewDidLoad

    {

    [super viewDidLoad];

    reader = [ZBarReaderViewController new];

    reader.readerDelegate = self;

    reader.wantsFullScreenLayout = NO;

    //隐藏底部控制按钮

    reader.showsZBarControls = NO;

    [self  setOverlayStyle:reader];//

    ZBarImageScanner *scanner = reader.scanner;

    [scanner setSymbology: ZBAR_I25

    config: ZBAR_CFG_ENABLE

    to: 0];

    }

    在button事件中添加跳转到扫描界面的代码。

    - (IBAction)btnClicked:(id)sender {

       [self presentViewController:reader animated:YES completion:Nil];

    }

    定义内置留言器 WebViewVC.h,拖拽一个uiwebview连接插座变量 aWebView。将uiwebview的delegate设置为self

    WebViewVC.h遵循协议 UIWebViewDelegate,

    在 WebViewVC.h定义全局变量:@property (nonatomic,retain) NSString* urlStr;

    在 WebViewVC.h的viewDidLoad加载网页。

    - (void)viewDidLoad

    {

    [super viewDidLoad];

    if (self.urlStr && [self.urlStr rangeOfString:@"http:"].length>0) {

    NSLog(@"%@",self.urlStr);

    NSURL *url =[NSURL URLWithString:self.urlStr];

    NSLog(@"open web with:%@",url);

    NSURLRequest *request =[NSURLRequest requestWithURL:url];

    _aWebView = [[UIWebView alloc]initWithFrame:self.view.frame];

    _aWebView.delegate =self;

    [self.view addSubview:_aWebView];

    [_aWebView loadRequest:request];

    }

    }

    最后再WSQViewController.h中处理扫描结果。

    在- (void) imagePickerController: (UIImagePickerController*) reader

    didFinishPickingMediaWithInfo: (NSDictionary*) info做扫描结果的判断:

    #pragma mark - ZBarReaderDelegate<UIImagePickerControllerDelegate>

    - (void) readerControllerDidFailToRead: (ZBarReaderController*) reader

        withRetry: (BOOL) retry

        {

        BlockAlertView *bAlert = [BlockAlertView alertWithTitle:@"结果:" message:@"扫描失败,无法读取二维码信息"];

        [bAlert addButtonWithTitle:@"知道了" block:nil];

        [bAlert show];

    }

        

        //二维码

    - (void) imagePickerController: (UIImagePickerController*) reader

        didFinishPickingMediaWithInfo: (NSDictionary*) info

        {

        

        // ADD: get the decode results

        id<NSFastEnumeration> results =

            [info objectForKey: ZBarReaderControllerResults];

            ZBarSymbol *symbol = nil;

            for(symbol in results)

            break;

            

            if(symbol.data && [symbol.data rangeOfString:@"http:"].length > 0)

            {

            

            NSString *regex = @"http+:[^\s]*";

            

            NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];

            //正则表达式判断是否包含 http:

            if ([predicate evaluateWithObject:symbol.data])

            {

            

            //判断是不是我们自己的二维码

            if ([symbol.data rangeOfString:@"http://itunes.apple.com/cn/app/id794862904"].length>0&& [[symbol.data componentsSeparatedByString:@"?"] count]>1) {

            

            NSString* strUrl =symbol.data;

            WebViewVC* web = [[WebViewVC alloc] initWithNibName:@"WebViewVC" bundle:nil];

            web.urlStr = strUrl;

            NSLog(@"strurl = %@",strUrl);

            UINavigationController* navi = [[UINavigationController alloc] initWithRootViewController:web];

            [reader presentViewController:navi animated:YES completion:nil];

            

            }else{

            [[UIApplication sharedApplication] openURL: [NSURL URLWithString:symbol.data]];

            }

            

            

            }else{

            //不是网页链接的情况。

            NSString* msgBody = [symbol.data stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

            BlockAlertView *bAlert = [BlockAlertView alertWithTitle:@"结果:" message:msgBody];

            [bAlert addButtonWithTitle:@"知道了" block:nil];

            [bAlert show];

            }

            

            }else if ([symbol.data rangeOfString:@"@@"].length > 0){

            

            NSArray* array  = [symbol.data componentsSeparatedByString:@"@@"];

            NSLog(@"ARRAY = %@",array);

            if (array && [array count]>0) {

            

            NSString *msg = [NSString stringWithFormat:@"",[array description]];

            

            BlockAlertView *bAlert = [BlockAlertView alertWithTitle:@"结果:" message:msg];

            

            NSMutableString* strBody = [[NSMutableString alloc] initWithCapacity:3];

            for (NSString*  str in array) {

            NSArray* tempArray = [str componentsSeparatedByString:@"["];

            if (tempArray&& [tempArray count]>0) {

            NSString* key = [tempArray objectAtIndex:0];

            NSString* valueStr = [tempArray objectAtIndex:1];

            NSString* value = [[valueStr componentsSeparatedByString:@"]"] objectAtIndex:0];

            if ([key isEqualToString:@"url"]) {

            [bAlert setCancelButtonWithTitle:@"打开网页" block:^{

            //在这里打开网页

            //[[UIApplication sharedApplication] openURL:[NSURL URLWithString: value]];

            

            [self openWebViewOf:value];

            }];

            }

            else if([key isEqualToString:@"tel"]){

            [bAlert setCancelButtonWithTitle:@"打电话" block:^{

            //在这里打开网页

            NSString* strTel = [NSString stringWithFormat:@"tel://%@",value];

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

            }];

            }

            }

            }

            [bAlert show];

            }

            }

            //[reader dismissViewControllerAnimated:YES completion:nil];

    }

    注:

    打开appstore下载app有两中方式。

    第一种:

    itms-apps://ax/itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReViews?type=Purpe+Software&id=794862904?mt=8"

    第二种:

    itms-apps://itunes.apple.com/cn/app/id794862904?url=http://xyk.cebbank.com,

    为了骗过第三方的扫描软件,比如,微信,淘宝,那么必须在连接中加上 http:// 这样才行。

    将第一种方式改成。

    http://ax/itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReViews?type=Purpe+Software&id=794862904?mt=8"在微信中还是不跳。

    那么就采用第二种方式。

    http://itunes.apple.com/cn/app/id794862904?url=http://xyk.cebbank.com

    这样的话就很容易的解决了微信扫一扫跳转的问题了,

    最开始,我甚至使用的一个网页连接,然后在打开网页的时候让网页重定向,但是微信死活就是不跳转,但是我又发现携程网的app二维码也是这种方式,携程可以跳,让我纠结了半天。最后查看携程的跳转连接。发现它总共跳转了四次如下,

    http://m.ctrip.com/m/c3,

    http://m.ctrip.com/market/download.aspx?from=c3,

    http://itunes.apple.com/cn/app/id379395415?mt=8,

    itms-apps://itunes.apple.com/cn/app/id379395415?mt=8,

    以我目前的情况是没时间搞它了,不知道有没有大牛给解答一下。

    最后附上我写的html跳转页面。

    <!DOCTYPE html">

    <html>

    <body>

    <script type="text/javascript">

    window.location = "mqq:open";

    window.location="itms-apps://itunes.apple.com/cn/app/794862904?mt=8";

    </script>

    <lable>

        是事实上是

    </lable>

    </body>

    </html>

     附上背景图:

  • 相关阅读:
    4单元练习
    3单元C#练习(重复太多,差别着写)
    ===习题
    .NET预习
    NET_.NET深入体验与实践精要----第四章
    NET 第一章
    C#认证考试试题汇编 Test
    _.NET深入体验与实战精要.pdf第四章
    C# 练习
    .NET 学习
  • 原文地址:https://www.cnblogs.com/wsq724439564/p/3553997.html
Copyright © 2011-2022 走看看