The QR Code Scanner package for Appeto SDK.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 
 

267 lignes
10 KiB

  1. //
  2. // QRView.swift
  3. // flutter_qr
  4. //
  5. // Created by Julius Canute on 21/12/18.
  6. //
  7. import Foundation
  8. import MTBBarcodeScanner
  9. public class QRView:NSObject,FlutterPlatformView {
  10. @IBOutlet var previewView: UIView!
  11. var scanner: MTBBarcodeScanner?
  12. var registrar: FlutterPluginRegistrar
  13. var channel: FlutterMethodChannel
  14. var cameraFacing: MTBCamera
  15. var QRCodeTypes = [
  16. 0: AVMetadataObject.ObjectType.aztec,
  17. 2: AVMetadataObject.ObjectType.code39,
  18. 3: AVMetadataObject.ObjectType.code93,
  19. 4: AVMetadataObject.ObjectType.code128,
  20. 5: AVMetadataObject.ObjectType.dataMatrix,
  21. 6: AVMetadataObject.ObjectType.ean8,
  22. 7: AVMetadataObject.ObjectType.ean13,
  23. 8: AVMetadataObject.ObjectType.interleaved2of5,
  24. 10: AVMetadataObject.ObjectType.pdf417,
  25. 11: AVMetadataObject.ObjectType.qr,
  26. 15: AVMetadataObject.ObjectType.upce
  27. ]
  28. public init(withFrame frame: CGRect, withRegistrar registrar: FlutterPluginRegistrar, withId id: Int64, params: Dictionary<String, Any>){
  29. self.registrar = registrar
  30. previewView = UIView(frame: frame)
  31. scanner = MTBBarcodeScanner(previewView: previewView)
  32. cameraFacing = MTBCamera.init(rawValue: UInt(Int(params["cameraFacing"] as! Double))) ?? MTBCamera.back
  33. channel = FlutterMethodChannel(name: "net.touchcapture.qr.flutterqr/qrview_\(id)", binaryMessenger: registrar.messenger())
  34. }
  35. deinit {
  36. scanner?.stopScanning()
  37. }
  38. public func view() -> UIView {
  39. channel.setMethodCallHandler({
  40. [weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
  41. switch(call.method){
  42. case "setDimensions":
  43. let arguments = call.arguments as! Dictionary<String, Double>
  44. self?.setDimensions(result,
  45. width: arguments["width"] ?? 0,
  46. height: arguments["height"] ?? 0,
  47. scanArea: arguments["scanArea"] ?? 0,
  48. scanAreaOffset: arguments["scanAreaOffset"] ?? 0)
  49. case "startScan":
  50. self?.startScan(call.arguments as! Array<Int>, result)
  51. case "flipCamera":
  52. self?.flipCamera(result)
  53. case "toggleFlash":
  54. self?.toggleFlash(result)
  55. case "pauseCamera":
  56. self?.pauseCamera(result)
  57. case "stopCamera":
  58. self?.stopCamera(result)
  59. case "resumeCamera":
  60. self?.resumeCamera(result)
  61. case "getCameraInfo":
  62. self?.getCameraInfo(result)
  63. case "getFlashInfo":
  64. self?.getFlashInfo(result)
  65. case "getSystemFeatures":
  66. self?.getSystemFeatures(result)
  67. default:
  68. result(FlutterMethodNotImplemented)
  69. return
  70. }
  71. })
  72. return previewView
  73. }
  74. func requestPermissions(_ result: @escaping FlutterResult) {
  75. MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in
  76. if permissionGranted {
  77. self.channel.invokeMethod("onPermissionSet", arguments: true)
  78. } else {
  79. return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil))
  80. }
  81. })
  82. }
  83. func setDimensions(_ result: @escaping FlutterResult, width: Double, height: Double, scanArea: Double, scanAreaOffset: Double) {
  84. // First ask for permission
  85. requestPermissions(result)
  86. // Then set the size of the preview area.
  87. self.previewView.frame = CGRect(x: 0, y: 0, width: width, height: height)
  88. // Then set the size of the scan area.
  89. let midX = self.view().bounds.midX
  90. let midY = self.view().bounds.midY
  91. // Set the size of the preview.
  92. if let previewLayer = self.scanner?.previewLayer {
  93. previewLayer.frame = self.previewView.bounds
  94. }
  95. // Set scanArea if provided.
  96. if (scanArea != 0) {
  97. self.scanner?.didStartScanningBlock = {
  98. self.scanner?.scanRect = CGRect(x: Double(midX) - (scanArea / 2), y: Double(midY) - (scanArea / 2), width: scanArea, height: scanArea)
  99. // Set offset if provided.
  100. if (scanAreaOffset != 0) {
  101. self.scanner?.scanRect = (self.scanner?.scanRect.offsetBy(dx: 0, dy: CGFloat(scanAreaOffset)))!
  102. }
  103. }
  104. }
  105. return result(width)
  106. }
  107. func startScan(_ arguments: Array<Int>, _ result: @escaping FlutterResult) {
  108. // Check for allowed barcodes
  109. var allowedBarcodeTypes: Array<AVMetadataObject.ObjectType> = []
  110. arguments.forEach { arg in
  111. allowedBarcodeTypes.append( QRCodeTypes[arg]!)
  112. }
  113. do {
  114. try self.scanner?.startScanning(with: self.cameraFacing, resultBlock: { [weak self] codes in
  115. if let codes = codes {
  116. for code in codes {
  117. var typeString: String;
  118. switch(code.type) {
  119. case AVMetadataObject.ObjectType.aztec:
  120. typeString = "AZTEC"
  121. case AVMetadataObject.ObjectType.code39:
  122. typeString = "CODE_39"
  123. case AVMetadataObject.ObjectType.code93:
  124. typeString = "CODE_93"
  125. case AVMetadataObject.ObjectType.code128:
  126. typeString = "CODE_128"
  127. case AVMetadataObject.ObjectType.dataMatrix:
  128. typeString = "DATA_MATRIX"
  129. case AVMetadataObject.ObjectType.ean8:
  130. typeString = "EAN_8"
  131. case AVMetadataObject.ObjectType.ean13:
  132. typeString = "EAN_13"
  133. case AVMetadataObject.ObjectType.itf14:
  134. typeString = "ITF"
  135. case AVMetadataObject.ObjectType.pdf417:
  136. typeString = "PDF_417"
  137. case AVMetadataObject.ObjectType.qr:
  138. typeString = "QR_CODE"
  139. case AVMetadataObject.ObjectType.upce:
  140. typeString = "UPC_E"
  141. default:
  142. return
  143. }
  144. guard let stringValue = code.stringValue else { continue }
  145. let result = ["code": stringValue, "type": typeString]
  146. if allowedBarcodeTypes.count == 0 || allowedBarcodeTypes.contains(code.type) {
  147. self?.channel.invokeMethod("onRecognizeQR", arguments: result)
  148. }
  149. }
  150. }
  151. })
  152. } catch {
  153. let error = FlutterError(code: "unknown-error", message: "Unable to start scanning", details: nil)
  154. return result(error)
  155. }
  156. }
  157. func stopCamera(_ result: @escaping FlutterResult) {
  158. if let sc: MTBBarcodeScanner = self.scanner {
  159. if sc.isScanning() {
  160. sc.stopScanning()
  161. }
  162. }
  163. }
  164. func getCameraInfo(_ result: @escaping FlutterResult) {
  165. result(self.cameraFacing.rawValue)
  166. }
  167. func flipCamera(_ result: @escaping FlutterResult) {
  168. if let sc: MTBBarcodeScanner = self.scanner {
  169. if sc.hasOppositeCamera() {
  170. sc.flipCamera()
  171. self.cameraFacing = sc.camera
  172. }
  173. return result(sc.camera.rawValue)
  174. }
  175. return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil))
  176. }
  177. func getFlashInfo(_ result: @escaping FlutterResult) {
  178. if let sc: MTBBarcodeScanner = self.scanner {
  179. result(sc.torchMode.rawValue != 0)
  180. } else {
  181. let error = FlutterError(code: "cameraInformationError", message: "Could not get flash information", details: nil)
  182. result(error)
  183. }
  184. }
  185. func toggleFlash(_ result: @escaping FlutterResult){
  186. if let sc: MTBBarcodeScanner = self.scanner {
  187. if sc.hasTorch() {
  188. sc.toggleTorch()
  189. return result(sc.torchMode == MTBTorchMode(rawValue: 1))
  190. }
  191. return result(FlutterError(code: "404", message: "This device doesn\'t support flash", details: nil))
  192. }
  193. return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil))
  194. }
  195. func pauseCamera(_ result: @escaping FlutterResult) {
  196. if let sc: MTBBarcodeScanner = self.scanner {
  197. if sc.isScanning() {
  198. sc.freezeCapture()
  199. }
  200. return result(true)
  201. }
  202. return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil))
  203. }
  204. func resumeCamera(_ result: @escaping FlutterResult) {
  205. if let sc: MTBBarcodeScanner = self.scanner {
  206. if !sc.isScanning() {
  207. sc.unfreezeCapture()
  208. }
  209. return result(true)
  210. }
  211. return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil))
  212. }
  213. func getSystemFeatures(_ result: @escaping FlutterResult) {
  214. if let sc: MTBBarcodeScanner = scanner {
  215. var hasBackCameraVar = false
  216. var hasFrontCameraVar = false
  217. let camera = sc.camera
  218. if(camera == MTBCamera(rawValue: 0)){
  219. hasBackCameraVar = true
  220. if sc.hasOppositeCamera() {
  221. hasFrontCameraVar = true
  222. }
  223. }else{
  224. hasFrontCameraVar = true
  225. if sc.hasOppositeCamera() {
  226. hasBackCameraVar = true
  227. }
  228. }
  229. return result([
  230. "hasFrontCamera": hasFrontCameraVar,
  231. "hasBackCamera": hasBackCameraVar,
  232. "hasFlash": sc.hasTorch(),
  233. "activeCamera": camera.rawValue
  234. ])
  235. }
  236. return result(FlutterError(code: "404", message: nil, details: nil))
  237. }
  238. }