ScanQRCodeViewController.swift 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. //
  2. // ScanQRCodeViewController.swift
  3. // JChat
  4. //
  5. // Created by 邓永豪 on 2017/8/16.
  6. // Copyright © 2017年 HXHG. All rights reserved.
  7. //
  8. import UIKit
  9. import UIKit
  10. import AVFoundation
  11. class ScanQRCodeViewController: UIViewController {
  12. override func viewDidLoad() {
  13. super.viewDidLoad()
  14. self.title = "扫一扫"
  15. view.backgroundColor = .white
  16. let authStatus = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
  17. if(authStatus == .restricted || authStatus == .denied){
  18. let alertView = UIAlertView(title: "无法访问相机", message: "请在设备的设置-趣阅中允许访问相机。",delegate: self, cancelButtonTitle: "好的", otherButtonTitles: "去设置")
  19. alertView.show()
  20. return;
  21. }
  22. previewLayer.frame = view.frame
  23. view.layer.addSublayer(previewLayer)
  24. session.startRunning()
  25. let borderView = UIImageView(frame: CGRect(x: (view.width - 240) / 2, y: 123, width: 240, height: 240))
  26. borderView.image = UIImage.loadImage("com_icon_qrc_border")
  27. view.addSubview(borderView)
  28. qrcLine = UIImageView(frame: CGRect(x: (view.width - 190) / 2, y: 123, width: 190, height: 6))
  29. qrcLine.image = UIImage.loadImage("com_icon_qrc_line")
  30. view.addSubview(qrcLine)
  31. let imageView = UIImageView(frame: view.frame)
  32. imageView.image = _getBackgroundImage()
  33. view.addSubview(imageView)
  34. let tipsLabel = UILabel(frame: CGRect(x: 0, y: 123 + 240 + 17.5, width: view.width, height: 20))
  35. tipsLabel.font = UIFont.systemFont(ofSize: 14)
  36. tipsLabel.text = "将取景框对准二维码,即可自动扫描"
  37. tipsLabel.textAlignment = .center
  38. tipsLabel.textColor = UIColor(netHex: 0x6EF8F8)
  39. view.addSubview(tipsLabel)
  40. NotificationCenter.default.addObserver(self, selector: #selector(startQRCAnimate), name: UIApplication.didBecomeActiveNotification, object: nil)
  41. }
  42. var qrcLine: UIImageView!
  43. var isStopAnimate = false
  44. override func viewWillAppear(_ animated: Bool) {
  45. super.viewWillAppear(animated)
  46. navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
  47. navigationController?.navigationBar.shadowImage = UIImage()
  48. }
  49. override func viewDidAppear(_ animated: Bool) {
  50. super.viewDidAppear(animated)
  51. session.startRunning()
  52. isStopAnimate = false
  53. isAnimating = false
  54. startQRCAnimate()
  55. }
  56. override func viewWillDisappear(_ animated: Bool) {
  57. super.viewWillDisappear(animated)
  58. navigationController?.navigationBar.setBackgroundImage(nil, for: .default)
  59. navigationController?.navigationBar.shadowImage = nil
  60. navigationController?.navigationBar.barTintColor = UIColor(netHex: 0x2dd0cf)
  61. self.qrcLine.layer.removeAllAnimations()
  62. }
  63. deinit {
  64. NotificationCenter.default.removeObserver(self)
  65. }
  66. fileprivate lazy var session: AVCaptureSession = {
  67. var session = AVCaptureSession()
  68. var device = AVCaptureDevice.default(for:AVMediaType.video)
  69. var input: AVCaptureDeviceInput?
  70. do {
  71. input = try AVCaptureDeviceInput(device: device!)
  72. } catch {
  73. print(error)
  74. }
  75. if input != nil {
  76. session.addInput(input!)
  77. }
  78. var output = AVCaptureMetadataOutput()
  79. session.addOutput(output)
  80. output.metadataObjectTypes = [AVMetadataObject.ObjectType.qr]
  81. output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
  82. return session
  83. }()
  84. fileprivate lazy var previewLayer: AVCaptureVideoPreviewLayer = {
  85. var previewLayer = AVCaptureVideoPreviewLayer(session: self.session)
  86. return previewLayer
  87. }()
  88. private func _getBackgroundImage() -> UIImage? {
  89. UIGraphicsBeginImageContext(view.frame.size)
  90. guard let ctx = UIGraphicsGetCurrentContext() else {
  91. return nil
  92. }
  93. ctx.setFillColor(red: 0, green: 0, blue: 0, alpha: 0.5)
  94. let screenSize = UIScreen.main.bounds.size
  95. var drawRect = CGRect(x: 0, y: 0, width: screenSize.width, height: screenSize.height)
  96. ctx.fill(drawRect)
  97. drawRect = CGRect(x: (view.width - 240) / 2, y: 123, width: 240, height: 240)
  98. ctx.clear(drawRect)
  99. let image = UIGraphicsGetImageFromCurrentImageContext()
  100. UIGraphicsEndImageContext()
  101. return image
  102. }
  103. var isAnimating = false
  104. @objc func startQRCAnimate() {
  105. if isStopAnimate || isAnimating {
  106. return
  107. }
  108. isAnimating = true
  109. qrcLine.frame = CGRect(x: (self.view.width - 190) / 2, y: 123, width: 190, height: 6)
  110. UIView.animate(withDuration: 2.5, animations: {
  111. self.qrcLine.frame = CGRect(x: (self.view.width - 190) / 2, y: 123 + 240 - 5, width: 190, height: 6)
  112. }) { (finish) in
  113. self.isAnimating = false
  114. self.qrcLine.frame = CGRect(x: (self.view.width - 190) / 2, y: 123, width: 190, height: 6)
  115. if finish {
  116. self.startQRCAnimate()
  117. }
  118. }
  119. }
  120. }
  121. // MARK: - AVCaptureMetadataOutputObjectsDelegate
  122. extension ScanQRCodeViewController: AVCaptureMetadataOutputObjectsDelegate {
  123. func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
  124. for metadataObject in metadataObjects {
  125. guard let object = metadataObject as? AVMetadataMachineReadableCodeObject else {
  126. return
  127. }
  128. let barCodeObject = previewLayer.transformedMetadataObject(for: object)
  129. let frame = barCodeObject!.bounds
  130. let validFrame = CGRect(x: (view.width - 240) / 2, y: 123, width: 240, height: 240)
  131. if frame.origin.x < validFrame.origin.x || frame.origin.x + frame.size.width > validFrame.origin.x + validFrame.size.width {
  132. return
  133. }
  134. if frame.size.width > validFrame.size.width {
  135. return
  136. }
  137. if frame.origin.y < validFrame.origin.y || frame.origin.y + frame.size.height > validFrame.origin.y + validFrame.size.height {
  138. return
  139. }
  140. if frame.size.height > validFrame.size.height {
  141. return
  142. }
  143. if object.type == AVMetadataObject.ObjectType.qr {
  144. guard let url = object.stringValue else {
  145. return
  146. }
  147. if let Url = URL(string: url) {
  148. if UIApplication.shared.canOpenURL(Url) {
  149. UIApplication.shared.openURL(Url)
  150. } else {
  151. let newUrl = URL(string: "https://" + url)
  152. UIApplication.shared.openURL(newUrl!)
  153. }
  154. return
  155. }
  156. let jsonData:Data = url.data(using: .utf8)!
  157. let dict = try? JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers)
  158. guard let info = dict as? NSDictionary else {
  159. return
  160. }
  161. guard let userInfo = info["user"] as? NSDictionary else {
  162. return
  163. }
  164. let username = userInfo["username"] as! String
  165. let appkey = userInfo["appkey"] as! String
  166. session.stopRunning()
  167. JMSGUser.userInfoArray(withUsernameArray: [username], appKey: appkey, completionHandler: { (result, error) in
  168. if error == nil {
  169. let users = result as! [JMSGUser]
  170. let user = users.first
  171. let vc = JCUserInfoViewController()
  172. vc.user = user
  173. self.navigationController?.pushViewController(vc, animated: true)
  174. }
  175. })
  176. }
  177. }
  178. }
  179. func convertStringToDictionary(text: String) -> [String : AnyObject]? {
  180. if let data = text.data(using: .utf8) {
  181. do {
  182. return try JSONSerialization.jsonObject(with: data, options: [JSONSerialization.ReadingOptions.init(rawValue: 0)]) as? [String:AnyObject]
  183. } catch let error as NSError {
  184. print(error)
  185. }
  186. }
  187. return nil
  188. }
  189. }
  190. extension ScanQRCodeViewController: UIAlertViewDelegate {
  191. func alertView(_ alertView: UIAlertView, clickedButtonAt buttonIndex: Int) {
  192. if buttonIndex == 1 {
  193. JCAppManager.openAppSetter()
  194. }
  195. }
  196. }