Swift4如何掃描二維碼了解一下

1.掃碼簡(jiǎn)史

這些年移動(dòng)互聯(lián)網(wǎng)的普及审姓,也讓二維碼技術(shù)成功的推廣蚓聘。在遙遠(yuǎn)的iOS7.0之前的年代壳鹤,我們實(shí)現(xiàn)二維碼掃描的功能鉴嗤,還需要借助兩大開源組件ZXing和ZBar來實(shí)現(xiàn)斩启。iOS7.0以后,蘋果提供了AVFoundation框架醉锅,來實(shí)現(xiàn)二維碼是掃碼兔簇,而且效率更高。
與此同時(shí)荣挨,蘋果的Swift開發(fā)語(yǔ)言男韧,也經(jīng)歷了從1.0誕生到4.1,其中不乏一些新特性以及API的變化默垄。

本文講解了如何用Swift4此虑,實(shí)現(xiàn)二維碼掃描的功能

2.具體實(shí)現(xiàn)

2.1權(quán)限控制

實(shí)現(xiàn)二維碼掃描,必然要打開手機(jī)攝像頭口锭,就需要獲取權(quán)限朦前。首先,在你的項(xiàng)目工程的info.plist中加入如下key-value鹃操,否則app調(diào)試的時(shí)候崩潰韭寸。

<key>NSCameraUsageDescription</key>
<string>CameraUsageDescription</string>

另外需要手動(dòng)去檢測(cè)當(dāng)前APP的攝像頭權(quán)限。如下代碼:

 func checkCameraAuth() -> Bool {
        let status = AVCaptureDevice.authorizationStatus(for: .video)
        return status == .authorized
 }

不難看出荆隘,status是個(gè)枚舉值恩伺,只有 .authorized才是已經(jīng)獲取攝像頭權(quán)限,其余的都不行椰拒。

2.2 上代碼

2.2.1 初始化

導(dǎo)入AVFoundation框架之后晶渠,我們就可以初始化捕捉設(shè)備、創(chuàng)建捕捉會(huì)話燃观、輸入媒體類型褒脯、設(shè)置代理等

// 捕捉設(shè)備
guard let device = AVCaptureDevice.default(for: .video)  else {
   return
}
do {
   // 輸入
    inPut: AVCaptureDeviceInput = try AVCaptureDeviceInput.init(device: device)
} catch  {
    print(error)
 }

 /// 輸出
 let outPut: AVCaptureMetadataOutput = {
        let outPut = AVCaptureMetadataOutput.init()
        outPut.connection(with: .metadata)
        return outPut
    }()

 /// 會(huì)話 session
 let session: AVCaptureSession = {
        let session = AVCaptureSession.init()
        if session.canSetSessionPreset(.high){
            session.sessionPreset = .high
        }
        return session
    }()

/// 預(yù)覽層
let preLayer: AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer.init()

2.2.2 設(shè)置代理

初始化之后,開始設(shè)置代理

// 設(shè)代理
outPut.setMetadataObjectsDelegate(self as AVCaptureMetadataOutputObjectsDelegate, queue: DispatchQueue.main)
// 指定預(yù)覽層的捕捉會(huì)話
preLayer.session = session

2.2.3 指定會(huì)話輸入輸出

然后把捕捉會(huì)話添加輸入輸出

// 捕捉會(huì)話加入input和output
  if session.canAddInput(input) && session.canAddOutput(outPut) {
            session.addInput(input)
            session.addOutput(outPut)
            // 設(shè)置元數(shù)據(jù)處理類型(注意, 一定要將設(shè)置元數(shù)據(jù)處理類型的代碼添加到  會(huì)話添加輸出之后)
            outPut.metadataObjectTypes = [.ean13, .ean8, .upce, .code39, .code93, .code128, .code39Mod43, .qr]
        }

設(shè)置元數(shù)據(jù)處理類型缆毁, 可見不僅有二維碼番川,而且還有其他條碼,就不一一介紹了脊框。注意, 一定要將設(shè)置元數(shù)據(jù)處理類型的代碼添加到會(huì)話添加輸出之后颁督。

2.2.4 添加會(huì)話預(yù)覽圖層

接著開始在頁(yè)面添加預(yù)覽層, 這樣才能看到攝像頭捕捉到的畫面。

 // 添加預(yù)覽圖層
let flag = view.layer.sublayers?.contains(preLayer)
if flag == false || flag == nil {
      self.preLayer.frame = view.bounds
      view.layer.insertSublayer(preLayer, at: 0)
}

2.2.5 開啟會(huì)話

到此為止缚陷,這個(gè)session捕捉會(huì)話需要的參數(shù)都全了适篙,然后開始愉快的開始這個(gè)會(huì)話

// 啟動(dòng)會(huì)話
session.startRunning()

2.2.6 監(jiān)聽捕捉會(huì)話輸出代理

開啟捕捉會(huì)話,我們就可以在代理方法中查看會(huì)話捕捉到的東西箫爷。

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!)

識(shí)別到的就在這個(gè)方法里告訴你。
什么?什么虎锚?硫痰,方法不調(diào)用?
敲黑板4芑ぁPО摺!API有變化了
Swift4.0的代理方法在下面

func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection){
    var resultStrs = [String]()
        for obj in metadataObjects {
            guard let codeObj = obj as? AVMetadataMachineReadableCodeObject else {
                return
            } 
            resultStrs.append(codeObj.stringValue ?? "")
        }
}

在這個(gè)方法里面就能拿到掃碼之后的結(jié)果了柱徙。

2.2.7 思考

寫到這里缓屠,不經(jīng)停下思考:
1.這里還只是基本的掃碼功能,就已經(jīng)這么多代碼了护侮,關(guān)于掃碼頁(yè)面的長(zhǎng)啥樣子的代碼我還沒寫敌完;
2.一般開發(fā)中頁(yè)面少不了UI的網(wǎng)絡(luò)的代碼,難道我要再把這么一大坨AVFoundation代碼都寫到控制器嗎羊初?
3.如果我一個(gè)項(xiàng)目里面滨溉,不止一個(gè)地方用到掃碼,難道我還要再把這么多代碼再?gòu)?fù)制幾遍

WTF.png

3.封裝

高內(nèi)聚 低耦合
就按照這個(gè)原則來封裝长赞。
1.首先把這些AVFoundation模塊的代碼晦攒,統(tǒng)統(tǒng)抽到一個(gè)工具類里,需要的時(shí)候得哆,直接拿工具類調(diào)用脯颜,識(shí)別結(jié)果delegate返回。
2.可以根據(jù)經(jīng)驗(yàn)贩据,把一些定制的需求也放進(jìn)去栋操,比如說掃碼的時(shí)候,中間透明的框框乐设,加上周邊的黑色蒙板讼庇。
3.擴(kuò)展一些其他功能,比如掃碼成功播放一段提示音等待

什么近尚?你準(zhǔn)備動(dòng)手了蠕啄?別著急,我已經(jīng)弄好了,使勁戳????

HRQRCodeScanTool

最簡(jiǎn)單的戈锻,在控制器中歼跟,你只需要

// in ViewController
HRQRCodeScanTool.shared.delegate  = self
HRQRCodeScanTool.shared.beginScanInView(view: view)

然后掃碼結(jié)果代理返回

// scan result will call in  delegate methods 
func scanQRCodeFaild(error: HRQRCodeTooError){
  print(error)
}

func scanQRCodeSuccess(resultStrs: [String]){
  print(resultStrs.first)
}

如果你需要二維碼描邊,你只需要設(shè)置這幾個(gè)屬性

open var isDrawQRCodeRect: Bool true    是否描繪二維碼邊框 默認(rèn)true
open var drawRectColor: UIColor UIColor.red 二維碼邊框顏色 默認(rèn)紅色
open var drawRectLineWith: CGFloat  2   二維碼邊框線寬 默認(rèn)2

如果你需要添加蒙板格遭,你只需要設(shè)置這幾個(gè)屬性

open var isShowMask: Bool   true    是否展示黑色蒙版板層 默認(rèn)開啟
open var maskColor: UIColor Black.alpha 0.5 蒙板層 默認(rèn)黑色 alpha 0.5
open var centerWidth: CGFloat   200 中心非蒙板區(qū)域的寬
open var centerHeight: CGFloat  5.0 中心非蒙板區(qū)域的寬
open var centerPosition: CGPoint?   nil 中心非蒙板區(qū)域的中心點(diǎn) 默認(rèn)Veiw的中心

哪里需要掃碼哈街,直接接入工具類,沒多少行代碼搞定拒迅,就問你爽不爽骚秦。
另外她倘,項(xiàng)目里還提供了兩個(gè)擴(kuò)展,用來識(shí)別二維碼圖片作箍,以及圖片生成二維碼硬梁,需要的各位看官老爺自取。


yeah.png

還支持Cocoapods哦

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末胞得,一起剝皮案震驚了整個(gè)濱河市荧止,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌阶剑,老刑警劉巖跃巡,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異牧愁,居然都是意外死亡素邪,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門递宅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來娘香,“玉大人,你說我怎么就攤上這事办龄『嬲溃” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵俐填,是天一觀的道長(zhǎng)安接。 經(jīng)常有香客問我,道長(zhǎng)英融,這世上最難降的妖魔是什么盏檐? 我笑而不...
    開封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮驶悟,結(jié)果婚禮上胡野,老公的妹妹穿的比我還像新娘。我一直安慰自己痕鳍,他們只是感情好硫豆,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著笼呆,像睡著了一般熊响。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上诗赌,一...
    開封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天汗茄,我揣著相機(jī)與錄音,去河邊找鬼铭若。 笑死洪碳,一個(gè)胖子當(dāng)著我的面吹牛递览,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播偶宫,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼非迹,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼环鲤!你這毒婦竟也來了纯趋?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤冷离,失蹤者是張志新(化名)和其女友劉穎吵冒,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體西剥,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡痹栖,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了瞭空。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片揪阿。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖咆畏,靈堂內(nèi)的尸體忽然破棺而出南捂,到底是詐尸還是另有隱情,我是刑警寧澤旧找,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布溺健,位于F島的核電站,受9級(jí)特大地震影響钮蛛,放射性物質(zhì)發(fā)生泄漏鞭缭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一魏颓、第九天 我趴在偏房一處隱蔽的房頂上張望岭辣。 院中可真熱鬧,春花似錦甸饱、人聲如沸沦童。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)搞动。三九已至,卻和暖如春渣刷,著一層夾襖步出監(jiān)牢的瞬間鹦肿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工辅柴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留箩溃,地道東北人瞭吃。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像涣旨,于是被迫代替她去往敵國(guó)和親歪架。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容