小編給大家分享一下iOS如何實(shí)現(xiàn)二維碼掃描和應(yīng)用跳轉(zhuǎn),希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
赤坎網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián),赤坎網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為赤坎近千家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)公司要多少錢(qián),請(qǐng)找那個(gè)售后服務(wù)好的赤坎做網(wǎng)站的公司定做!
前面我們已經(jīng)調(diào)到過(guò)怎么制作二維碼,在我們能夠生成二維碼之后,如何對(duì)二維碼進(jìn)行掃描呢?
在iOS7之前,大部分應(yīng)用中使用的二維碼掃描是第三方的掃描框架,例如ZXing或者ZBar。使用時(shí)集成麻煩,出錯(cuò)也不方便調(diào)試。在iOS7之后,蘋(píng)果自身提供了二維碼的掃描功能,從效率上來(lái)說(shuō),原生的二維碼遠(yuǎn)高于這些第三方框架。本文講解如何使用原生框架實(shí)現(xiàn)二維碼掃描功能,并且進(jìn)行掃描后的項(xiàng)目跳轉(zhuǎn)。
掃描相關(guān)類
二維碼掃描需要獲取攝像頭并讀取照片信息,因此我們需要導(dǎo)入系統(tǒng)的AVFoundation框架,創(chuàng)建視頻會(huì)話。我們需要用到一下幾個(gè)類:
AVCaptureSession 會(huì)話對(duì)象。此類作為硬件設(shè)備輸入輸出信息的橋梁,承擔(dān)實(shí)時(shí)獲取設(shè)備數(shù)據(jù)的責(zé)任
AVCaptureDeviceInput 設(shè)備輸入類。這個(gè)類用來(lái)表示輸入數(shù)據(jù)的硬件設(shè)備,配置抽象設(shè)備的port
AVCaptureMetadataOutput 輸出類。這個(gè)支持二維碼、條形碼等圖像數(shù)據(jù)的識(shí)別
AVCaptureVideoPreviewLayer 圖層類。用來(lái)快速呈現(xiàn)攝像頭獲取的原始數(shù)據(jù) 二維碼掃描功能的實(shí)現(xiàn)步驟是創(chuàng)建好會(huì)話對(duì)象,用來(lái)獲取從硬件設(shè)備輸入的數(shù)據(jù),并實(shí)時(shí)顯示在界面上。在掃描到相應(yīng)圖像數(shù)據(jù)的時(shí)候,通過(guò)AVCaptureVideoPreviewLayer類型進(jìn)行返回
應(yīng)用跳轉(zhuǎn)
在使用第三方登陸、分享sdk的時(shí)候,我們的項(xiàng)目會(huì)在本機(jī)安裝有目標(biāo)平臺(tái)的應(yīng)用的情況下進(jìn)行應(yīng)用跳轉(zhuǎn),并且傳遞信息過(guò)去。這在沙盒機(jī)制下的iOS應(yīng)用而言,理應(yīng)是不符合規(guī)則的。但是,iOS SDK給我們提供了一個(gè)叫做url scheme的機(jī)制來(lái)實(shí)現(xiàn)這個(gè)功能。
url scheme讓我們可以像使用Safari打開(kāi)網(wǎng)頁(yè)的方式跳轉(zhuǎn)到其他應(yīng)用中,并使用類似網(wǎng)絡(luò)請(qǐng)求的GET請(qǐng)求的參數(shù)拼湊方式來(lái)在不同應(yīng)用之間傳遞數(shù)據(jù)。
使用url scheme的第一步是在項(xiàng)目的info.plist文件中添加新row,命名為URL types
展開(kāi)新增的字典,我們修改其中的URL Identifier以及新增加一個(gè)字段
URL Schemes。
Identifier用來(lái)跳轉(zhuǎn)后,讓跳轉(zhuǎn)應(yīng)用識(shí)別從哪里跳轉(zhuǎn)過(guò)來(lái)的,我們可以設(shè)置為bundleID反轉(zhuǎn),來(lái)確保其特殊性。
URL Schemes是一個(gè)數(shù)組,我們將在這個(gè)數(shù)組里面自定義自己的url schemes,這里我們填寫(xiě)應(yīng)用名。最終效果如下:
接著,我們就可以在其他應(yīng)用中通過(guò)openURL:方法打開(kāi)我們的app。
二維碼掃描
二維碼掃描的步驟:
1、創(chuàng)建設(shè)備會(huì)話對(duì)象,用來(lái)設(shè)置設(shè)備數(shù)據(jù)輸入
2、獲取攝像頭,并且將攝像頭對(duì)象加入當(dāng)前會(huì)話中
3、實(shí)時(shí)獲取攝像頭原始數(shù)據(jù)顯示在屏幕上
4、掃描到二維碼/條形碼數(shù)據(jù),通過(guò)協(xié)議方法回調(diào)
(1)會(huì)話對(duì)象AVCaptureSession的創(chuàng)建
_session = [AVCaptureSession new]; [_session setSessionPreset: AVCaptureSessionPresetHigh]; //高質(zhì)量采集 [self setupIODevice];
(2)setupIODevice方法中懶加載方式創(chuàng)建輸入對(duì)象和輸出對(duì)象,注意必須在輸出數(shù)據(jù)對(duì)象加入到當(dāng)前會(huì)話后才能設(shè)置識(shí)別的數(shù)據(jù)格式。這里設(shè)置為掃描二維碼以及條形碼
[_session addInput: self.input]; [_session addOutput: self.output]; _output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];
(3)創(chuàng)建AVCaptureMetadataOutput設(shè)置好掃描成功回調(diào)代理以及回調(diào)線程
_output = [AVCaptureMetadataOutput new]; [_output setMetadataObjectsDelegate: self queue: dispatch_get_main_queue()];
(4)創(chuàng)建AVCaptureDeviceInput輸入設(shè)備為手機(jī)攝像頭
AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo]; _input = [AVCaptureDeviceInput deviceInputWithDevice: device error: nil];
(5)創(chuàng)建AVCaptureVideoPreviewLayer對(duì)象來(lái)實(shí)時(shí)獲取攝像頭圖像,我們需要調(diào)用[self.view addSubview: self.scanView]把攝像頭獲取的圖像實(shí)時(shí)展示在屏幕上
_scanView = [AVCaptureVideoPreviewLayer layerWithSession: self.session]; _scanView.videoGravity = AVLayerVideoGravityResizeAspectFill; _scanView.frame = self.bounds;
(6)實(shí)現(xiàn)captureOutput: didOutputMetadataObjects: fromConnection:來(lái)獲取掃描得到的數(shù)據(jù)。回調(diào)參數(shù)metadataObjects中存放了掃描結(jié)果,我們需要先判斷這個(gè)數(shù)組的數(shù)據(jù)個(gè)數(shù)不為0再執(zhí)行下面的代碼:
[self stop]; AVMetadataMachineReadableCodeObject * metadataObject = metadataObjects[0]; if ([self.delegate respondsToSelector: @selector(scanView:codeInfo:)]) { [self.delegate scanView: self codeInfo: metadataObject.stringValue]; [self removeFromSuperview]; } else { [[NSNotificationCenter defaultCenter] postNotificationName: LXDSuccessScanQRCodeNotification object: self userInfo: @{ LXDScanQRCodeMessageKey: metadataObject.stringValue }];
讀取二維碼信息進(jìn)行應(yīng)用跳轉(zhuǎn)
首先要說(shuō)明的是,二維碼并非一定要存儲(chǔ)應(yīng)用的url scheme。例如公眾號(hào)的二維碼,雖然不知道是怎樣的數(shù)據(jù)存儲(chǔ),但肯定不是應(yīng)用跳轉(zhuǎn)。可以給自己的應(yīng)用指定一個(gè)二維碼數(shù)據(jù)規(guī)則,例如支付寶付款掃描是讀取商品的ID、價(jià)格等信息,然后進(jìn)行頁(yè)面跳轉(zhuǎn)付款。
這里我們使用上面設(shè)置的url scheme,我們通過(guò)制作二維碼方法來(lái)定制一個(gè)存儲(chǔ)應(yīng)用跳轉(zhuǎn)信息的二維碼,通過(guò)下面的代理創(chuàng)建一個(gè)存儲(chǔ)url scheme(使用url scheme的時(shí)候要注意在后面加上://后才能使用openURL進(jìn)行跳轉(zhuǎn))的二維碼,這一步應(yīng)該放到模擬器上面生成
- (IBAction)createBarcode:(id)sender { UIImage * image = [UIImage imageOfQRFromURL: @"LXDDrawLosts://" codeSize: 160.f red: 123 green: 189 blue: 229 insertImage: nil]; CGSize size = image.size; UIImageView * imageView = [[UIImageView alloc] initWithFrame: ((CGRect){(CGPointZero), (size)})]; imageView.center = self.view.center; imageView.image = image; [self.view addSubview: imageView]; }
創(chuàng)建二維碼掃描控制器,然后對(duì)我們生成的二維碼進(jìn)行掃描(這一步要在真機(jī)上面完成,上面url scheme的應(yīng)用應(yīng)當(dāng)通過(guò)xcode安裝在手機(jī)上,才能完成跳轉(zhuǎn))
LXDScanCodeController * scanCodeController = [LXDScanCodeController scanCodeController]; scanCodeController.scanDelegate = self; [self.navigationController pushViewController: scanCodeController animated: YES];
掃描成功后判斷是否可以打開(kāi)跳轉(zhuǎn),如果你的應(yīng)用有一套二維碼數(shù)據(jù)存儲(chǔ)的規(guī)則,那么在不能跳轉(zhuǎn)的時(shí)候應(yīng)該按照這套規(guī)則解析數(shù)據(jù)。這里我直接在無(wú)法跳轉(zhuǎn)的情況下顯示警告框告訴用戶無(wú)法解析二維碼:
NSURL * url = [NSURL URLWithString: codeInfo]; if ([[UIApplication sharedApplication] canOpenURL: url]) { [[UIApplication sharedApplication] openURL: url]; } else { UIAlertView ** * alertView = [[UIAlertView alloc] initWithTitle: @"警告" message: [NSString stringWithFormat: @"%@:%@", @"無(wú)法解析的二維碼", codeInfo] delegate: nil cancelButtonTitle: @"確定" otherButtonTitles: nil]; [alertView show]; }
按照上面的步驟進(jìn)行的話,那么在你掃完二維碼之后,你的手機(jī)就會(huì)跳轉(zhuǎn)到剛才設(shè)置url scheme的應(yīng)用中。
掃描優(yōu)化
上面已經(jīng)完成了二維碼的掃描功能實(shí)現(xiàn),但是現(xiàn)在你會(huì)發(fā)現(xiàn)我們?cè)谑褂蒙厦娲a進(jìn)行掃描的時(shí)候,整個(gè)屏幕都是掃描范圍,這樣會(huì)影響掃描的準(zhǔn)確性以及我們調(diào)整掃描范圍的難度。
蘋(píng)果提供了一種方式讓我們規(guī)定掃描范圍:在AVCaptureMetadataOutput
中有一個(gè)叫做rectOfInterest
的CGRect類型屬性,這個(gè)屬性用來(lái)限制掃描范圍。
這個(gè)屬性的每一個(gè)值取值范圍在0~1之間,代表的是對(duì)應(yīng)軸上的比例大小。最開(kāi)始我以為這個(gè)是以左上角為原點(diǎn),后來(lái)設(shè)置為CGRectMake(0.3, 0.35, 0.4, 0.3)
發(fā)現(xiàn)和預(yù)期的不一樣,因?yàn)檫@個(gè)屬性是以屏幕右上角為坐標(biāo)原點(diǎn),并且寬高的順序要對(duì)換過(guò)來(lái)
如圖所示,由于坐標(biāo)系的不同,原本CGRectMake(0.3, 0.35, 0.4, 0.3)
到了新坐標(biāo)系中就變成了CGRectMake(0.35, 0.3, 0.3, 0.4)
。那么大家設(shè)置成新的掃描范圍之后,重新運(yùn)行掃描程序,看看效果——然而,我們發(fā)現(xiàn)并不能掃描成功,這是因?yàn)檫@個(gè)掃描區(qū)域不僅僅是坐標(biāo)系原點(diǎn)發(fā)生了改變。如下圖所示
按照上面CGRect的設(shè)置,我是想要把掃描范圍控制在屏幕x軸上面0.3-0.7,y軸上0.35-0.65之間的范圍。但是在這個(gè)屬性中,width和height分別表示的是在rectOfInterest坐標(biāo)中掃描矩形右下角的坐標(biāo)點(diǎn)位置。因此,這個(gè)掃描范圍應(yīng)該是CGRectMake(0.35, 0.3, 0.65, 0.7)
。除了設(shè)置好掃描范圍之內(nèi),我們還可以仿照微信的掃描,給非掃描范圍加上一層半透明的黑色layer
應(yīng)用傳值
前面說(shuō)過(guò),url scheme不僅僅支持應(yīng)用跳轉(zhuǎn),它還支持使用類似get請(qǐng)求的方式在應(yīng)用間傳值。上面跳轉(zhuǎn)的url scheme是LXDDrawLosts://
,那么類似get請(qǐng)求,我們?cè)谶@個(gè)字符串后面加上一個(gè)?表示區(qū)分開(kāi)參數(shù)和應(yīng)用id,使用&分隔不同參數(shù),然后后面按照字段名=屬性值
的方式拼湊鏈接。
比如,假設(shè)這是一個(gè)即時(shí)通訊app,那么我可以制定這樣的一個(gè)跳轉(zhuǎn)參數(shù)規(guī)則:
method 表示操作類型
userId 用戶id
title 分享標(biāo)題
message 分享消息
link_url 分享鏈接
那么,如果傳入的是
LXDDrawLosts://?method=addFriends&userId=10086
這可能代表的是掃描后添加id為10086的新好友。
又比如
LXDDrawLosts://?method=shareMessage&title=分享測(cè)試&message=這是林欣達(dá)的分享測(cè)試&link_url=http://www.jianshu.com/users/0cf7d455eb9e/latest_articles
這代表分享信息到你的app中。這些都是我們自己的應(yīng)用可以制定的規(guī)則,如果有興趣,可以新浪微博開(kāi)放平臺(tái)或者騰訊開(kāi)放平臺(tái),他們的文檔中應(yīng)該有url scheme的傳值標(biāo)準(zhǔn)。
說(shuō)完了通過(guò)url scheme傳入?yún)?shù)后,怎么把這些參數(shù)取出來(lái)呢?AppDelegate中提供了application:openURL: sourceApplication: annotation:
方法讓我們可以取出傳入的值。
在我們通過(guò)url scheme跳轉(zhuǎn)到本應(yīng)用的時(shí)候,這個(gè)方法就會(huì)被系統(tǒng)調(diào)用。其中,有兩個(gè)重要的參數(shù)需要我們知道
sourceApplication
這個(gè)字符串保存了跳轉(zhuǎn)方app的url Identifier,就是上文中除了url scheme以外的另一個(gè)字段
url
這個(gè)鏈接中存儲(chǔ)了跳轉(zhuǎn)的url scheme以及參數(shù)列表,我們通過(guò)[url scheme]方法獲取前者;用[url query]方法獲取?之后的參數(shù)列表,然后使用字符串的分隔方法把這些數(shù)據(jù)讀取出來(lái)
單純的二維碼數(shù)據(jù)并沒(méi)有過(guò)于強(qiáng)大的功能,但結(jié)合了url scheme的跳轉(zhuǎn)機(jī)制后,二維碼能夠幫助我們的應(yīng)用獲得更加強(qiáng)大的能力,使得我們的應(yīng)用之間有了更多聯(lián)系。
看完了這篇文章,相信你對(duì)“iOS如何實(shí)現(xiàn)二維碼掃描和應(yīng)用跳轉(zhuǎn)”有了一定的了解,如果想了解更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!
網(wǎng)頁(yè)名稱:iOS如何實(shí)現(xiàn)二維碼掃描和應(yīng)用跳轉(zhuǎn)
標(biāo)題URL:http://aaarwkj.com/article46/igjjeg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、全網(wǎng)營(yíng)銷推廣、關(guān)鍵詞優(yōu)化、企業(yè)網(wǎng)站制作、外貿(mào)建站、網(wǎng)站收錄
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)