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.
 
 
 
 
 
 

327 lignes
15 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. cameraFacing = MTBCamera.init(rawValue: UInt(Int(params["cameraFacing"] as! Double))) ?? MTBCamera.back
  32. channel = FlutterMethodChannel(name: "net.touchcapture.qr.flutterqr/qrview_\(id)", binaryMessenger: registrar.messenger())
  33. }
  34. deinit {
  35. scanner?.stopScanning()
  36. }
  37. public func view() -> UIView {
  38. channel.setMethodCallHandler({
  39. [weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
  40. switch(call.method){
  41. case "setDimensions":
  42. let arguments = call.arguments as! Dictionary<String, Double>
  43. self?.setDimensions(result,
  44. width: arguments["width"] ?? 0,
  45. height: arguments["height"] ?? 0,
  46. scanArea: arguments["scanArea"] ?? 0,
  47. scanAreaOffset: arguments["scanAreaOffset"] ?? 0)
  48. case "startScan":
  49. self?.startScan(call.arguments as! Array<Int>, result)
  50. case "flipCamera":
  51. self?.flipCamera(result)
  52. case "toggleFlash":
  53. self?.toggleFlash(result)
  54. case "pauseCamera":
  55. self?.pauseCamera(result)
  56. case "stopCamera":
  57. self?.stopCamera(result)
  58. case "resumeCamera":
  59. self?.resumeCamera(result)
  60. case "getCameraInfo":
  61. self?.getCameraInfo(result)
  62. case "getFlashInfo":
  63. self?.getFlashInfo(result)
  64. case "getSystemFeatures":
  65. self?.getSystemFeatures(result)
  66. default:
  67. result(FlutterMethodNotImplemented)
  68. return
  69. }
  70. })
  71. return previewView
  72. }
  73. func setDimensions(_ result: @escaping FlutterResult, width: Double, height: Double, scanArea: Double, scanAreaOffset: Double) -> Void {
  74. MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in
  75. if permissionGranted {
  76. // self?.channel.invokeMethod("onPermissionSet", arguments: true)
  77. // First set the size of the preview area.
  78. self.previewView.frame = CGRect(x: 0, y: 0, width: width, height: height)
  79. // Then set the size of the scan area.
  80. let midX = self.view().bounds.midX
  81. let midY = self.view().bounds.midY
  82. // Check if the scanner is already created.
  83. if let sc: MTBBarcodeScanner = self.scanner {
  84. if let previewLayer = sc.previewLayer {
  85. previewLayer.frame = self.previewView.bounds;
  86. }
  87. if (scanArea != 0) {
  88. sc.scanRect = CGRect(x: Double(midX) - (scanArea / 2), y: Double(midY) - (scanArea / 2), width: scanArea, height: scanArea)
  89. // Set offset if provided.
  90. if (scanAreaOffset != 0) {
  91. sc.scanRect = sc.scanRect.offsetBy(dx: 0, dy: CGFloat(scanAreaOffset))
  92. }
  93. }
  94. } else {
  95. // Create a scanner view if it doesn't exist yet.
  96. self.scanner = MTBBarcodeScanner(previewView: self.previewView)
  97. if (scanArea != 0) {
  98. self.scanner?.didStartScanningBlock = {
  99. self.scanner?.scanRect = CGRect(x: Double(midX) - (scanArea / 2), y: Double(midY) - (scanArea / 2), width: scanArea, height: scanArea)
  100. // Set offset if provided.
  101. if (scanAreaOffset != 0) {
  102. self.scanner?.scanRect = (self.scanner?.scanRect.offsetBy(dx: 0, dy: CGFloat(scanAreaOffset)))!
  103. }
  104. }
  105. }
  106. }
  107. return result(width)
  108. } else {
  109. return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil))
  110. }
  111. })
  112. }
  113. func startScan(_ arguments: Array<Int>, _ result: @escaping FlutterResult) -> Void {
  114. if (scanner == nil) {
  115. scanner = MTBBarcodeScanner(previewView: previewView)
  116. }
  117. var allowedBarcodeTypes: Array<AVMetadataObject.ObjectType> = []
  118. arguments.forEach { arg in
  119. allowedBarcodeTypes.append( QRCodeTypes[arg]!)
  120. }
  121. MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in
  122. if permissionGranted {
  123. self.channel.invokeMethod("onPermissionSet", arguments: true)
  124. do {
  125. try self.scanner?.startScanning(with: self.cameraFacing, resultBlock: { [weak self] codes in
  126. if let codes = codes {
  127. for code in codes {
  128. var typeString: String;
  129. switch(code.type) {
  130. case AVMetadataObject.ObjectType.aztec:
  131. typeString = "AZTEC"
  132. case AVMetadataObject.ObjectType.code39:
  133. typeString = "CODE_39"
  134. case AVMetadataObject.ObjectType.code93:
  135. typeString = "CODE_93"
  136. case AVMetadataObject.ObjectType.code128:
  137. typeString = "CODE_128"
  138. case AVMetadataObject.ObjectType.dataMatrix:
  139. typeString = "DATA_MATRIX"
  140. case AVMetadataObject.ObjectType.ean8:
  141. typeString = "EAN_8"
  142. case AVMetadataObject.ObjectType.ean13:
  143. typeString = "EAN_13"
  144. case AVMetadataObject.ObjectType.itf14:
  145. typeString = "ITF"
  146. case AVMetadataObject.ObjectType.pdf417:
  147. typeString = "PDF_417"
  148. case AVMetadataObject.ObjectType.qr:
  149. typeString = "QR_CODE"
  150. case AVMetadataObject.ObjectType.upce:
  151. typeString = "UPC_E"
  152. default:
  153. return
  154. }
  155. guard let stringValue = code.stringValue else { continue }
  156. let result = ["code": stringValue, "type": typeString]
  157. if allowedBarcodeTypes.count == 0 || allowedBarcodeTypes.contains(code.type) {
  158. self?.channel.invokeMethod("onRecognizeQR", arguments: result)
  159. }
  160. }
  161. }
  162. })
  163. } catch {
  164. let error = FlutterError(code: "unknown-error", message: "Unable to start scanning", details: nil)
  165. return result(error)
  166. }
  167. } else {
  168. return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil))
  169. }
  170. })
  171. }
  172. func stopCamera(_ result: @escaping FlutterResult){
  173. MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in
  174. if permissionGranted {
  175. if let sc: MTBBarcodeScanner = self.scanner {
  176. if sc.isScanning() {
  177. sc.stopScanning()
  178. }
  179. }
  180. } else {
  181. return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil))
  182. }
  183. })
  184. }
  185. func getCameraInfo(_ result: @escaping FlutterResult) -> Void {
  186. MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in
  187. if permissionGranted {
  188. if let sc: MTBBarcodeScanner = self.scanner {
  189. result(sc.camera.rawValue)
  190. } else {
  191. let error = FlutterError(code: "cameraInformationError", message: "Could not get camera information", details: nil)
  192. result(error)
  193. }
  194. } else {
  195. return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil))
  196. }
  197. })
  198. }
  199. func flipCamera(_ result: @escaping FlutterResult){
  200. MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in
  201. if permissionGranted {
  202. if let sc: MTBBarcodeScanner = self.scanner {
  203. if sc.hasOppositeCamera() {
  204. sc.flipCamera()
  205. }
  206. return result(sc.camera.rawValue)
  207. }
  208. return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil))
  209. } else {
  210. return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil))
  211. }
  212. })
  213. }
  214. func getFlashInfo(_ result: @escaping FlutterResult) -> Void {
  215. MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in
  216. if permissionGranted {
  217. if let sc: MTBBarcodeScanner = self.scanner {
  218. result(sc.torchMode.rawValue != 0)
  219. } else {
  220. let error = FlutterError(code: "cameraInformationError", message: "Could not get flash information", details: nil)
  221. result(error)
  222. }
  223. } else {
  224. return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil))
  225. }
  226. })
  227. }
  228. func toggleFlash(_ result: @escaping FlutterResult){
  229. MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in
  230. if permissionGranted {
  231. if let sc: MTBBarcodeScanner = self.scanner {
  232. if sc.hasTorch() {
  233. sc.toggleTorch()
  234. return result(sc.torchMode == MTBTorchMode(rawValue: 1))
  235. }
  236. return result(FlutterError(code: "404", message: "This device doesn\'t support flash", details: nil))
  237. }
  238. return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil))
  239. } else {
  240. return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil))
  241. }
  242. })
  243. }
  244. func pauseCamera(_ result: @escaping FlutterResult) {
  245. MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in
  246. if permissionGranted {
  247. if let sc: MTBBarcodeScanner = self.scanner {
  248. if sc.isScanning() {
  249. sc.freezeCapture()
  250. }
  251. return result(true)
  252. }
  253. return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil))
  254. } else {
  255. return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil))
  256. }
  257. })
  258. }
  259. func resumeCamera(_ result: @escaping FlutterResult) {
  260. MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in
  261. if permissionGranted {
  262. if let sc: MTBBarcodeScanner = self.scanner {
  263. if !sc.isScanning() {
  264. sc.unfreezeCapture()
  265. }
  266. return result(true)
  267. }
  268. return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil))
  269. } else {
  270. return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil))
  271. }
  272. })
  273. }
  274. func getSystemFeatures(_ result: @escaping FlutterResult) -> Void {
  275. if let sc: MTBBarcodeScanner = scanner {
  276. var hasBackCameraVar = false
  277. var hasFrontCameraVar = false
  278. let camera = sc.camera
  279. if(camera == MTBCamera(rawValue: 0)){
  280. hasBackCameraVar = true
  281. if sc.hasOppositeCamera() {
  282. hasFrontCameraVar = true
  283. }
  284. }else{
  285. hasFrontCameraVar = true
  286. if sc.hasOppositeCamera() {
  287. hasBackCameraVar = true
  288. }
  289. }
  290. return result([
  291. "hasFrontCamera": hasFrontCameraVar,
  292. "hasBackCamera": hasBackCameraVar,
  293. "hasFlash": sc.hasTorch(),
  294. "activeCamera": camera.rawValue
  295. ])
  296. }
  297. return result(FlutterError(code: "404", message: nil, details: nil))
  298. }
  299. }