iOS掃一掃功能開發,ios掃一掃
之前很多二維碼掃描都是基於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