123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578 |
- //
- // ScanVC.m
- // jiaPei
- //
- // Created by apple on 16/4/19.
- // Copyright © 2016年 JCZ. All rights reserved.
- //
- #import "ScanVC.h"
- #import <AVFoundation/AVFoundation.h>
- #import "DES3Util.h"
- #import "Tools.h"
- #define KWidth (kSize.width/2.0 + 30)
- @interface ScanVC ()<AVCaptureMetadataOutputObjectsDelegate>
- {
- BOOL isDown;
- NSTimer *timer;
- NSInteger num;
- UIImageView *scanBackground;
- UIImageView *line;
- AVCaptureDevice *device;
- AVCaptureSession *session;
- AVCaptureDeviceInput *input;
- AVCaptureMetadataOutput *output;
- AVCaptureVideoPreviewLayer *preview;
-
- NSInteger order;
- NSString *dataString;
- }
- @end
- @implementation ScanVC
- - (void)viewDidLoad {
- [super viewDidLoad];
-
- self.view.backgroundColor = backGroundColor;
- self.title = @"二维码扫描";
- [self configNavigationBar];
- scanBackground = [[UIImageView alloc] initWithFrame:CGRectMake((kSize.width - KWidth)/2.0, (kSize.height - KWidth)/2.0 - kNavOffSet, KWidth, KWidth)];
- scanBackground.image = [[UIImage imageNamed:@"scanBackground.png"] tint:RQ_MAIN_COLOR];
- [self.view addSubview:scanBackground];
-
- line = [[UIImageView alloc] initWithFrame:CGRectMake(CGRectGetMinX(scanBackground.frame)+5, CGRectGetMinY(scanBackground.frame)+5, KWidth-10,2)];
- line.image = [[UIImage imageNamed:@"scanLine.png"] tint:RQ_MAIN_COLOR];
- [self.view addSubview:line];
-
- [self setOverView];
- [self initScan];
-
- order = 0;
- isDown = YES;
- num = 0;
- timer = [NSTimer scheduledTimerWithTimeInterval:.05 target:self selector:@selector(timeRunToAnimation) userInfo:nil repeats:YES];
- }
- -(void)viewWillAppear:(BOOL)animated
- {
- [super viewWillAppear:animated];
- num = 0; //让先从最上面开始扫描
- if (timer) {
- [timer setFireDate:[NSDate distantPast]];
- }
- if (session && ![session isRunning]) {
- [session startRunning];
- }
- }
- -(void)viewWillDisappear:(BOOL)animated
- {
- [super viewWillDisappear:animated];
- if (timer) {
- [timer setFireDate:[NSDate distantFuture]];
- }
- if (session && [session isRunning]) {
- [session stopRunning];
- }
- }
- - (void)timeRunToAnimation {
- if (isDown) {
- num ++;
- if (num > (KWidth-10)/2.0) {
- isDown = NO;
- }
- }else{
- num --;
- if (num == 0) {
- isDown = YES;
- }
- }
-
- line.frame = CGRectMake(CGRectGetMinX(scanBackground.frame)+5, CGRectGetMinY(scanBackground.frame)+5 + num*2, KWidth-10,2);
- }
- //二维码操作
- -(void)initScan
- {
- NSString *mediaType = AVMediaTypeVideo;
- AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:mediaType];
- if (authStatus == AVAuthorizationStatusRestricted || authStatus == AVAuthorizationStatusDenied) {
- [self.navigationController popViewControllerAnimated:YES];
-
- [RQ_SHARE_FUNCTION showAlertWithTitle:@"温馨提示" message:@"请在iPhone的“设置”-“隐私”-“相机”功能中,找到“极速驾培”打开相机访问权限" alertControllerStyle:UIAlertControllerStyleAlert cancelButtonTitle:@"取消" otherButtonTitles:@[@"确定"] otherButtonStyles:nil showInWindow:NO completion:^(NSUInteger selectedOtherButtonIndex) {
- if (selectedOtherButtonIndex == 0) {
- NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
- if ([[UIApplication sharedApplication] canOpenURL:url]) {
- [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
- }
- }
- }];
-
- return;
- }
-
- //获取设备
- device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
- //输入流
- input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
-
- //输出流
- output = [[AVCaptureMetadataOutput alloc] init];
- //设置代理
-
- //(kSize.width - KWidth)/2.0, (kSize.height - KWidth)/2.0, KWidth, KWidth)
- //这里添加一点 这样就很容易扫到码了
- CGRect rect = scanBackground.frame;
- rect.origin.x = (kSize.width - KWidth - 80)/2.0;
- rect.origin.y = (kSize.height - KWidth - 80)/2.0;
- rect.size.width = rect.size.height = KWidth + 80;
-
- [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
- output.rectOfInterest =[self rectOfInterestByScanViewRect:rect];
-
- //NSLog(@"%@",output.rectOfInterest);
-
- //起连接作用的回执
- session = [[AVCaptureSession alloc] init];
- [session setSessionPreset:AVCaptureSessionPresetHigh];
- if ([session canAddInput:input]){
- [session addInput:input];
- }
- if ([session canAddOutput:output]){
- [session addOutput:output];
- }
-
- //指定output所能扫描的类型
- output.metadataObjectTypes = @[AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypeQRCode];
-
- //界面
- preview = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
- preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
- preview.frame = self.view.bounds;
- [self.view.layer insertSublayer:preview atIndex:0];
- [self.view bringSubviewToFront:scanBackground];
-
-
- //开始扫描
- [session startRunning];
-
- }
- //扫描到的信息通过output的协议方法返回
- - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
- {
- if (metadataObjects.count > 0)
- {
- AVMetadataMachineReadableCodeObject *object = [metadataObjects firstObject];
- //session关闭
- [session stopRunning];
- [timer setFireDate:[NSDate distantFuture]];
-
- //需要我们对接的二维码抬头
- if ([object.stringValue containsString:@"#DECODE#"] && object.stringValue.length > 8) {
-
- BOOL SP_IS_MNQisTure = NO;
- for (ParamsItem *item in RQ_USER_MANAGER.currentUser.params) {
- if ([item.KEY isEqualToString:@"SP_IS_MNQ"]) {
- if ([item.VALUE isEqualToString:@"1"]) {
- SP_IS_MNQisTure = YES;
- }
- }
- }
-
- //程序内某些验证
- NSString *testString = [DES3Util decrypt:[object.stringValue substringFromIndex:8]];
- NSArray *scanArray = [testString componentsSeparatedByString:@";"];
- /* 是APP的二维码*/
- if ([[scanArray firstObject] isEqualToString:@"#JSDTMO#"]) {
-
- //二维码是否过期
- NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
- formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
- [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
- NSDate *scanDate = [formatter dateFromString:[scanArray lastObject]];
- NSTimeInterval time = [scanDate timeIntervalSinceNow];
- if (time < 0) {
- ShowMsg(@"二维码信息已过期");
- [session startRunning];
- [timer setFireDate:[NSDate distantPast]];
- return;
- }
-
- /*
- 非计划实操计时
- 标识符 type 教练outID 教练姓名 价格 科目 教练手机号码 终端设备号 有效时间
- */
- if ([scanArray[1] isEqualToString:@"signIn"]) {
-
- if(self.type == 2){
- [self showMsgByAlertControllerWithString:@"二维码类型错误,请扫描\"模拟计时\"二维码"];
- return;
- }
-
- order = 1;
- dataString = [[testString componentsSeparatedByString:@"signIn;"] lastObject];
- [self alertShowWithString:[NSString stringWithFormat:@"当前所选为%@教练,是否开始实操练习?",scanArray[3]]];
-
- return;
- }
-
-
- /*
- 计划实操计时
- 标识符 type 教练outID 教练姓名 学生证号 预约ID 电话号码 终端设备号 有效时间
- */
- if ([scanArray[1] isEqualToString:@"planSignIn"]) {
-
- if(self.type == 2){
- [self showMsgByAlertControllerWithString:@"二维码类型错误,请扫描\"模拟计时\"二维码"];
- return;
- }
-
- if (![scanArray[4] isEqualToString:RQ_USER_MANAGER.currentUser._id]) {
- ShowMsg(@"当前准教学员信息与本人不符,请核对二维码");
- [Tools playAudioWithString:@"当前准教学员信息与本人不符,请核对二维码"];
- [session startRunning];
- [timer setFireDate:[NSDate distantPast]];
- return;
- }
-
-
- order = 2;
- dataString = [[testString componentsSeparatedByString:@"planSignIn;"] lastObject];
-
- [self alertShowWithString:[NSString stringWithFormat:@"当前所选为%@教练,是否开始实操练习?",scanArray[3]]];
-
- return;
- }
-
-
- /*
- 实操结束计时
- 标识符 type 教练outID 学生身份证明 有效时间
- */
-
- if ([scanArray[1] isEqualToString:@"signOut"] || [scanArray[1] isEqualToString:@"planSignOut"]) {
-
- if(self.type == 2){
- [self showMsgByAlertControllerWithString:@"二维码类型错误,请扫描\"模拟计时\"二维码"];
- return;
- }
-
- NSDictionary *gatherTrainDic;
- NSString *filePath = [Tools getPathWithFileName:@"gatherTrainDic.plist"];
- if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
-
- gatherTrainDic = [NSMutableDictionary dictionaryWithContentsOfFile:filePath];
- }
-
- if ([gatherTrainDic[@"isPlan"] isEqualToString:@"1"] && [scanArray[1] isEqualToString:@"signOut"]) {
- ShowMsg(@"请选择正确结束方式!");
- return;
- }
- if ([gatherTrainDic[@"isPlan"] isEqualToString:@"2"] && [scanArray[1] isEqualToString:@"planSignOut"]) {
- ShowMsg(@"请选择正确结束方式!");
- return;
- }
-
- NSString *identString = RQ_USER_MANAGER.currentUser.outId;
- if ([scanArray[1] isEqualToString:@"planSignOut"]) {
- identString = RQ_USER_MANAGER.currentUser._id;
- }
- if (![scanArray[3] isEqualToString:identString]) {
- ShowMsg(@"当前准教学员信息与本人不符,请核对二维码");
- [Tools playAudioWithString:@"当前准教学员信息与本人不符,请核对二维码"];
- [session startRunning];
- [timer setFireDate:[NSDate distantPast]];
- return;
- }
-
- order = 3;
- if ([scanArray[1] isEqualToString:@"signOut"]) {
- dataString = [[testString componentsSeparatedByString:@"signOut;"] lastObject];
- }else{
- dataString = [[testString componentsSeparatedByString:@"planSignOut;"] lastObject];
- }
-
- [self alertShowWithString:[NSString stringWithFormat:@"结束实操练习?"]];
- return;
- }
-
- /*
- 模拟开始计时
- 标识符 type 教练outID 教练名字 教练经度 教练纬度 有效时间
- */
-
- if ([scanArray[1] isEqualToString:@"imitSignIn"]) {
-
- if (self.type == 1) {
- [self showMsgByAlertControllerWithString:@"二维码类型错误,请扫描\"实操计时\"二维码"];
- return;
- }
-
- if (SP_IS_MNQisTure) {
- ShowMsg(@"请使用模拟机设备计时");
- [session startRunning];
- [timer setFireDate:[NSDate distantPast]];
- return;
- }
-
- order = 4;
- dataString = [[testString componentsSeparatedByString:@"imitSignIn;"] lastObject];
- [self alertShowWithString:[NSString stringWithFormat:@"当前所选为%@教练,是否开始模拟练习?",scanArray[3]]];
- return;
- }
- /*模拟设备(非app二维码)(不包含#JSDTMO#)*/
- }else if ([[scanArray firstObject] isEqualToString:@"#MNQ#"]){
-
- if (self.type == 1) {
- [self showMsgByAlertControllerWithString:@"二维码类型错误,请扫描\"实操计时\"二维码"];
- return;
- }
-
- /*
- 模拟开始 模拟设备打模拟学时
- #MNQ#;序列号(devSn);动态码(dynamicCode);签到/签退类型(1签到 3签退)
- */
-
- if (!SP_IS_MNQisTure) {
- ShowMsg(@"暂不能使用模拟起设备");
- [session startRunning];
- [timer setFireDate:[NSDate distantPast]];
- return;
- }
-
- order = 5;
- dataString = [[testString componentsSeparatedByString:@"#MNQ#;"] lastObject];
-
- NSString *showString = @"正在进行模拟计时签到,是否开始模拟练习?";
- if ([[NSString stringWithFormat:@"%@",[scanArray lastObject]] isEqualToString:@"2"]) {
- showString = @"签退";
- }
- [self alertShowWithString:showString];
- return;
-
- }else{
- //包含#decode# 非@"#JSDTMO#" 非#MNQ#
- }
-
- }
-
- /*无须我们对接的二维码(不包含#DECODE#)*/
- if (self.type == 1) {
- [self showMsgByAlertControllerWithString:@"二维码类型错误,请扫描\"实操计时\"二维码"];
- }else if(self.type == 2){
- [self showMsgByAlertControllerWithString:@"二维码类型错误,请扫描\"模拟计时\"二维码"];
- }
-
-
- //判断是否进入进某网址
- // if ([object.stringValue containsString:@".com"] || [object.stringValue containsString:@".cn"]) {
- // [[UIApplication sharedApplication] openURL:[NSURL URLWithString:object.stringValue]];
- // [self.navigationController popViewControllerAnimated:YES];
- // return;
- // }
-
- //扫码网页登录用
- // order = -1;
- // dataString = object.stringValue;
- // [self alertShowWithString:@"是否允许登录公众平台?"];
- }
- }
- -(void)showMsgByAlertControllerWithString:(NSString *)str {
- [RQ_SHARE_FUNCTION showAlertWithTitle:@"提示" message:str alertControllerStyle:UIAlertControllerStyleAlert cancelButtonTitle:@"重新扫描" otherButtonTitles:@[@"退出"] otherButtonStyles:nil showInWindow:NO completion:^(NSUInteger selectedOtherButtonIndex) {
- switch (selectedOtherButtonIndex) {
- case NSNotFound: {
- //取消就重新打开扫描
- [session startRunning];
- [timer setFireDate:[NSDate distantPast]];
- break;
- }
- case 0: {
- [self.navigationController popViewControllerAnimated:YES];
- break;
- }
- default:
- break;
- }
- }];
-
- // UIAlertController *alertFind = [UIAlertController alertControllerWithTitle:@"提示" message:str preferredStyle:UIAlertControllerStyleAlert];
- //
- // [alertFind addAction:[UIAlertAction actionWithTitle:@"重新扫描" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
- // //取消就重新打开扫描
- // [session startRunning];
- // [timer setFireDate:[NSDate distantPast]];
- // }]];
- // [alertFind addAction:[UIAlertAction actionWithTitle:@"退出" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
- // [self.navigationController popViewControllerAnimated:YES];
- // }]];
- // [self presentViewController:alertFind animated:true completion:nil];
-
- }
- - (void)alertShowWithString:(NSString *)string {
- [RQ_SHARE_FUNCTION showAlertWithTitle:@"温馨提示" message:string alertControllerStyle:UIAlertControllerStyleAlert cancelButtonTitle:@"取消" otherButtonTitles:@[@"确定"] otherButtonStyles:nil showInWindow:NO completion:^(NSUInteger selectedOtherButtonIndex) {
- if (selectedOtherButtonIndex == 0) {
- switch (order) {
- case -1:
- {
- [self downloadFJJP];
- }
- break;
- case 1://非计划实操计时
- {
- NSDictionary *dic = @{@"scanType":@"scPeriod",@"dataString":dataString};
- if (scanBlock) {
- scanBlock(dic);
- [self.navigationController popViewControllerAnimated:YES];
- }
- }
- break;
- case 2://计划实操计时
- {
- NSDictionary *dic = @{@"scanType":@"jhPeriod",@"dataString":dataString};
- if (scanBlock) {
- scanBlock(dic);
- [self.navigationController popViewControllerAnimated:YES];
- }
- }
- break;
- case 3://结束计时
- {
- NSDictionary *dic = @{@"scanType":@"allSignOut",@"dataString":dataString};
- if (scanBlock) {
- scanBlock(dic);
- [self.navigationController popViewControllerAnimated:YES];
- }
- }
- break;
- case 4://模拟计时开始
- {
- NSDictionary *dic = @{@"scanType":@"imPeriod",@"dataString":dataString};
- if (scanBlock) {
- scanBlock(dic);
- [self.navigationController popViewControllerAnimated:YES];
- }
- }
- break;
-
- case 5://模拟计时开始/结束
- {
- NSDictionary *dic = @{@"scanType":@"imitatePeriod",@"dataString":dataString};
- if (scanBlock) {
- scanBlock(dic);
- [self.navigationController popViewControllerAnimated:YES];
- }
- }
- break;
-
- default:
- break;
- }
- }else if (selectedOtherButtonIndex == NSNotFound) {
- //取消就重新打开扫描
- [session startRunning];
- [timer setFireDate:[NSDate distantPast]];
- return;
- }
- }];
- }
- //登录网页社会公众平台
- -(void)downloadFJJP
- {
- if (!dataString || dataString.length < 1) {
- [session startRunning];
- [timer setFireDate:[NSDate distantPast]];
- return;
- }
- //发送请求
- [LoadingView showHUD];
- NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
- NSString *account = [ud objectForKey:@"identifyNum"];
- NSString *key = [ud objectForKey:@"password"];
- NSString *params = [NSString stringWithFormat:@"%@;%@;%@",dataString,account,key];
-
- //NSLog(@"获取的二维码---->%@----\nparams---->%@\n---->%@",object.stringValue,params,[DES3Util encrypt:params]);
- NSString *URL = [NSString stringWithFormat:@"http://www.jppt.com.cn/gzpt/index/phoneLogin?params=%@",[DES3Util encrypt:params]];
- NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
- [request setURL:[NSURL URLWithString:URL]];
- [request setHTTPMethod:@"GET"];
-
- NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
- // 返回数据转为字符串
- RemoveHUD();
- NSString *dataStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
-
- if ([dataStr isEqualToString:@"true"]) {
-
- ShowMsg(@"登录成功");
- [self.navigationController popViewControllerAnimated:YES];
- }else{
-
- ShowMsg(@"登录失败");
- [session startRunning];
- [timer setFireDate:[NSDate distantPast]];
- }
- }];
- [task resume];
- }
- -(void)scanBlock:(MyBlockType)block
- {
- scanBlock = block;
- }
- - (CGRect)rectOfInterestByScanViewRect:(CGRect)rect {
- CGFloat width = CGRectGetWidth(self.view.frame);
- CGFloat height = CGRectGetHeight(self.view.frame);
-
- CGFloat x = (height - CGRectGetHeight(rect)) / 2 / height;
- CGFloat y = (width - CGRectGetWidth(rect)) / 2 / width;
-
- CGFloat w = CGRectGetHeight(rect) / height;
- CGFloat h = CGRectGetWidth(rect) / width;
-
- return CGRectMake(x, y, w, h);
- }
- #pragma mark - 添加模糊效果
- - (void)setOverView {
- CGFloat width = CGRectGetWidth(self.view.frame);
- CGFloat height = CGRectGetHeight(self.view.frame);
-
- CGFloat x = CGRectGetMinX(scanBackground.frame);
- CGFloat y = CGRectGetMinY(scanBackground.frame);
- CGFloat w = CGRectGetWidth(scanBackground.frame);
- CGFloat h = CGRectGetHeight(scanBackground.frame);
-
- [self creatView:CGRectMake(0, 0, width, y)];
- [self creatView:CGRectMake(0, y, x, h)];
- [self creatView:CGRectMake(0, y + h, width, height - y - h)];
- [self creatView:CGRectMake(x + w, y, width - x - w, h)];
- }
- - (void)creatView:(CGRect)rect {
- CGFloat alpha = 0.5;
- UIColor *backColor = [UIColor grayColor];
- UIView *view = [[UIView alloc] initWithFrame:rect];
- view.backgroundColor = backColor;
- view.alpha = alpha;
- [self.view addSubview:view];
- }
- - (void)didReceiveMemoryWarning {
- [super didReceiveMemoryWarning];
- }
- @end
|