日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

二维码扫描和应用跳转

發(fā)布時間:2023/12/20 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二维码扫描和应用跳转 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

轉(zhuǎn)載自: http://sindrilin.com/ios-dev/2015/11/01/二維碼掃描和應(yīng)用跳轉(zhuǎn).html

?

前面我們已經(jīng)調(diào)到過怎么制作二維碼,在我們能夠生成二維碼之后,如何對二維碼進(jìn)行掃描呢?

在iOS7之前,大部分應(yīng)用中使用的二維碼掃描是第三方的掃描框架,例如ZXing或者ZBar。使用時集成麻煩,出錯也不方便調(diào)試。在iOS7之后,蘋果自身提供了二維碼的掃描功能,從效率上來說,原生的二維碼遠(yuǎn)高于這些第三方框架。本文講解如何使用原生框架實現(xiàn)二維碼掃描功能,并且進(jìn)行掃描后的項目跳轉(zhuǎn)。

掃描相關(guān)類

二維碼掃描需要獲取攝像頭并讀取照片信息,因此我們需要導(dǎo)入系統(tǒng)的AVFoundation框架,創(chuàng)建視頻會話。我們需要用到一下幾個類:

  • AVCaptureSession?會話對象。此類作為硬件設(shè)備輸入輸出信息的橋梁,承擔(dān)實時獲取設(shè)備數(shù)據(jù)的責(zé)任
  • AVCaptureDeviceInput?設(shè)備輸入類。這個類用來表示輸入數(shù)據(jù)的硬件設(shè)備,配置抽象設(shè)備的port
  • AVCaptureMetadataOutput?輸出類。這個支持二維碼、條形碼等圖像數(shù)據(jù)的識別
  • AVCaptureVideoPreviewLayer?圖層類。用來快速呈現(xiàn)攝像頭獲取的原始數(shù)據(jù) 二維碼掃描功能的實現(xiàn)步驟是創(chuàng)建好會話對象,用來獲取從硬件設(shè)備輸入的數(shù)據(jù),并實時顯示在界面上。在掃描到相應(yīng)圖像數(shù)據(jù)的時候,通過AVCaptureVideoPreviewLayer類型進(jìn)行返回

應(yīng)用跳轉(zhuǎn)

在使用第三方登陸、分享sdk的時候,我們的項目會在本機(jī)安裝有目標(biāo)平臺的應(yīng)用的情況下進(jìn)行應(yīng)用跳轉(zhuǎn),并且傳遞信息過去。這在沙盒機(jī)制下的iOS應(yīng)用而言,理應(yīng)是不符合規(guī)則的。但是,iOS SDK給我們提供了一個叫做url scheme的機(jī)制來實現(xiàn)這個功能。

url scheme讓我們可以像使用Safari打開網(wǎng)頁的方式跳轉(zhuǎn)到其他應(yīng)用中,并使用類似網(wǎng)絡(luò)請求的GET請求的參數(shù)拼湊方式來在不同應(yīng)用之間傳遞數(shù)據(jù)。

使用url scheme的第一步是在項目的info.plist文件中添加新row,命名為URL types

展開新增的字典,我們修改其中的URL Identifier以及新增加一個字段
URL Schemes。
Identifier用來跳轉(zhuǎn)后,讓跳轉(zhuǎn)應(yīng)用識別從哪里跳轉(zhuǎn)過來的,我們可以設(shè)置為bundleID反轉(zhuǎn),來確保其特殊性。
URL Schemes是一個數(shù)組,我們將在這個數(shù)組里面自定義自己的url schemes,這里我們填寫應(yīng)用名。最終效果如下:

接著,我們就可以在其他應(yīng)用中通過openURL:方法打開我們的app。

二維碼掃描

二維碼掃描的步驟:

1、創(chuàng)建設(shè)備會話對象,用來設(shè)置設(shè)備數(shù)據(jù)輸入
2、獲取攝像頭,并且將攝像頭對象加入當(dāng)前會話中
3、實時獲取攝像頭原始數(shù)據(jù)顯示在屏幕上
4、掃描到二維碼/條形碼數(shù)據(jù),通過協(xié)議方法回調(diào)

  • 會話對象AVCaptureSession的創(chuàng)建

    _session = [AVCaptureSession new]; [_session setSessionPreset: AVCaptureSessionPresetHigh]; //高質(zhì)量采集 [self setupIODevice];
  • setupIODevice方法中懶加載方式創(chuàng)建輸入對象和輸出對象,注意必須在輸出數(shù)據(jù)對象加入到當(dāng)前會話后才能設(shè)置識別的數(shù)據(jù)格式。這里設(shè)置為掃描二維碼以及條形碼

    [_session addInput: self.input]; [_session addOutput: self.output]; _output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];
  • 創(chuàng)建AVCaptureMetadataOutput設(shè)置好掃描成功回調(diào)代理以及回調(diào)線程

    _output = [AVCaptureMetadataOutput new]; [_output setMetadataObjectsDelegate: self queue: dispatch_get_main_queue()];
  • 創(chuàng)建AVCaptureDeviceInput輸入設(shè)備為手機(jī)攝像頭

    AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo]; _input = [AVCaptureDeviceInput deviceInputWithDevice: device error: nil];
  • 創(chuàng)建AVCaptureVideoPreviewLayer對象來實時獲取攝像頭圖像,我們需要調(diào)用[self.view addSubview: self.scanView]把攝像頭獲取的圖像實時展示在屏幕上

    _scanView = [AVCaptureVideoPreviewLayer layerWithSession: self.session]; _scanView.videoGravity = AVLayerVideoGravityResizeAspectFill; _scanView.frame = self.bounds;
  • 實現(xiàn)captureOutput: didOutputMetadataObjects: fromConnection:來獲取掃描得到的數(shù)據(jù)。回調(diào)參數(shù)metadataObjects中存放了掃描結(jié)果,我們需要先判斷這個數(shù)組的數(shù)據(jù)個數(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)

首先要說明的是,二維碼并非一定要存儲應(yīng)用的url scheme。例如公眾號的二維碼,雖然不知道是怎樣的數(shù)據(jù)存儲,但肯定不是應(yīng)用跳轉(zhuǎn)。可以給自己的應(yīng)用指定一個二維碼數(shù)據(jù)規(guī)則,例如支付寶付款掃描是讀取商品的ID、價格等信息,然后進(jìn)行頁面跳轉(zhuǎn)付款。
這里我們使用上面設(shè)置的url scheme,我們通過制作二維碼方法來定制一個存儲應(yīng)用跳轉(zhuǎn)信息的二維碼,通過下面的代理創(chuàng)建一個存儲url scheme(使用url scheme的時候要注意在后面加上://后才能使用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)建二維碼掃描控制器,然后對我們生成的二維碼進(jìn)行掃描(這一步要在真機(jī)上面完成,上面url scheme的應(yīng)用應(yīng)當(dāng)通過xcode安裝在手機(jī)上,才能完成跳轉(zhuǎn))

LXDScanCodeController * scanCodeController = [LXDScanCodeController scanCodeController]; scanCodeController.scanDelegate = self; [self.navigationController pushViewController: scanCodeController animated: YES];

掃描成功后判斷是否可以打開跳轉(zhuǎn),如果你的應(yīng)用有一套二維碼數(shù)據(jù)存儲的規(guī)則,那么在不能跳轉(zhuǎn)的時候應(yīng)該按照這套規(guī)則解析數(shù)據(jù)。這里我直接在無法跳轉(zhuǎn)的情況下顯示警告框告訴用戶無法解析二維碼:

NSURL * url = [NSURL URLWithString: codeInfo]; if ([[UIApplication sharedApplication] canOpenURL: url]) {[[UIApplication sharedApplication] openURL: url]; } else {UIAlertView ** * alertView = [[UIAlertView alloc] initWithTitle: @"警告" message: [NSString stringWithFormat: @"%@:%@", @"無法解析的二維碼", codeInfo] delegate: nil cancelButtonTitle: @"確定" otherButtonTitles: nil];[alertView show]; }

按照上面的步驟進(jìn)行的話,那么在你掃完二維碼之后,你的手機(jī)就會跳轉(zhuǎn)到剛才設(shè)置url scheme的應(yīng)用中。

掃描優(yōu)化

上面已經(jīng)完成了二維碼的掃描功能實現(xiàn),但是現(xiàn)在你會發(fā)現(xiàn)我們在使用上面代碼進(jìn)行掃描的時候,整個屏幕都是掃描范圍,這樣會影響掃描的準(zhǔn)確性以及我們調(diào)整掃描范圍的難度。
蘋果提供了一種方式讓我們規(guī)定掃描范圍:在AVCaptureMetadataOutput中有一個叫做rectOfInterest的CGRect類型屬性,這個屬性用來限制掃描范圍。
這個屬性的每一個值取值范圍在0~1之間,代表的是對應(yīng)軸上的比例大小。最開始我以為這個是以左上角為原點,后來設(shè)置為CGRectMake(0.3, 0.35, 0.4, 0.3)發(fā)現(xiàn)和預(yù)期的不一樣,因為這個屬性是以屏幕右上角為坐標(biāo)原點,并且寬高的順序要對換過來

如圖所示,由于坐標(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)并不能掃描成功,這是因為這個掃描區(qū)域不僅僅是坐標(biāo)系原點發(fā)生了改變。如下圖所示

按照上面CGRect的設(shè)置,我是想要把掃描范圍控制在屏幕x軸上面0.3-0.7,y軸上0.35-0.65之間的范圍。但是在這個屬性中,width和height分別表示的是在rectOfInterest坐標(biāo)中掃描矩形右下角的坐標(biāo)點位置。因此,這個掃描范圍應(yīng)該是CGRectMake(0.35, 0.3, 0.65, 0.7)。除了設(shè)置好掃描范圍之內(nèi),我們還可以仿照微信的掃描,給非掃描范圍加上一層半透明的黑色layer


應(yīng)用傳值

前面說過,url scheme不僅僅支持應(yīng)用跳轉(zhuǎn),它還支持使用類似get請求的方式在應(yīng)用間傳值。上面跳轉(zhuǎn)的url scheme是LXDDrawLosts://,那么類似get請求,我們在這個字符串后面加上一個?表示區(qū)分開參數(shù)和應(yīng)用id,使用&分隔不同參數(shù),然后后面按照字段名=屬性值的方式拼湊鏈接。
比如,假設(shè)這是一個即時通訊app,那么我可以制定這樣的一個跳轉(zhuǎn)參數(shù)規(guī)則:

  • method?表示操作類型
  • userId?用戶id
  • title?分享標(biāo)題
  • message?分享消息
  • link_url?分享鏈接

那么,如果傳入的是
LXDDrawLosts://?method=addFriends&userId=10086
這可能代表的是掃描后添加id為10086的新好友。

又比如

LXDDrawLosts://?method=shareMessage&title=分享測試&message=這是林欣達(dá)的分享測試&link_url=http://www.jianshu.com/users/0cf7d455eb9e/latest_articles
這代表分享信息到你的app中。這些都是我們自己的應(yīng)用可以制定的規(guī)則,如果有興趣,可以新浪微博開放平臺或者騰訊開放平臺,他們的文檔中應(yīng)該有url scheme的傳值標(biāo)準(zhǔn)。

說完了通過url scheme傳入?yún)?shù)后,怎么把這些參數(shù)取出來呢?AppDelegate中提供了application:openURL: sourceApplication: annotation:方法讓我們可以取出傳入的值。
在我們通過url scheme跳轉(zhuǎn)到本應(yīng)用的時候,這個方法就會被系統(tǒng)調(diào)用。其中,有兩個重要的參數(shù)需要我們知道

  • sourceApplication?這個字符串保存了跳轉(zhuǎn)方app的url Identifier,就是上文中除了url scheme以外的另一個字段
  • url?這個鏈接中存儲了跳轉(zhuǎn)的url scheme以及參數(shù)列表,我們通過[url scheme]方法獲取前者;用[url query]方法獲取?之后的參數(shù)列表,然后使用字符串的分隔方法把這些數(shù)據(jù)讀取出來

單純的二維碼數(shù)據(jù)并沒有過于強(qiáng)大的功能,但結(jié)合了url scheme的跳轉(zhuǎn)機(jī)制后,二維碼能夠幫助我們的應(yīng)用獲得更加強(qiáng)大的能力,使得我們的應(yīng)用之間有了更多聯(lián)系。

轉(zhuǎn)載于:https://www.cnblogs.com/hissia/p/5690392.html

總結(jié)

以上是生活随笔為你收集整理的二维码扫描和应用跳转的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。