二維碼介紹:javascript
二維碼(QR(Quick Response)code),又稱二維條碼,最先起源於日本。html
它是用特定的幾何圖形按必定規律在平面(二維方向)上分佈的黑白相間的圖形,是全部信息數據的一把鑰匙。java
二維碼是一種比一維碼更高級的條碼格式。一維碼只能在一個方向(通常是水平方向)上表達信息,git
而二維碼在水平和垂直方向均可以存儲信息。一維碼只能由數字和字母組成,而二維碼能存儲漢字、數字和圖片等信息,github
所以二維碼的應用領域要廣得多。web
二維碼需求:正則表達式
開發一款二維碼掃描插件,具備掃描大衆二維碼的能力,可以識別二維碼當中包含的網頁連接以及文本信息。對網頁連接跳轉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>
附上背景圖: