The QR Code Scanner package for Appeto SDK.
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 
 
 
 

266 рядки
11 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) {
  74. // Then set the size of the preview area.
  75. previewView.frame = CGRect(x: 0, y: 0, width: width, height: height)
  76. // Then set the size of the scan area.
  77. let midX = self.view().bounds.midX
  78. let midY = self.view().bounds.midY
  79. if let sc: MTBBarcodeScanner = scanner {
  80. // Set the size of the preview if preview is already created.
  81. if let previewLayer = sc.previewLayer {
  82. previewLayer.frame = self.previewView.bounds
  83. }
  84. } else {
  85. // Create new preview.
  86. scanner = MTBBarcodeScanner(previewView: previewView)
  87. }
  88. // Set scanArea if provided.
  89. if (scanArea != 0) {
  90. scanner?.didStartScanningBlock = {
  91. self.scanner?.scanRect = CGRect(x: Double(midX) - (scanArea / 2), y: Double(midY) - (scanArea / 2), width: scanArea, height: scanArea)
  92. // Set offset if provided.
  93. if (scanAreaOffset != 0) {
  94. let reversedOffset = -scanAreaOffset
  95. self.scanner?.scanRect = (self.scanner?.scanRect.offsetBy(dx: 0, dy: CGFloat(reversedOffset)))!
  96. }
  97. }
  98. }
  99. return result(width)
  100. }
  101. func startScan(_ arguments: Array<Int>, _ result: @escaping FlutterResult) {
  102. // Check for allowed barcodes
  103. var allowedBarcodeTypes: Array<AVMetadataObject.ObjectType> = []
  104. arguments.forEach { arg in
  105. allowedBarcodeTypes.append( QRCodeTypes[arg]!)
  106. }
  107. MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in
  108. if permissionGranted {
  109. do {
  110. try self.scanner?.startScanning(with: self.cameraFacing, resultBlock: { [weak self] codes in
  111. if let codes = codes {
  112. for code in codes {
  113. var typeString: String;
  114. switch(code.type) {
  115. case AVMetadataObject.ObjectType.aztec:
  116. typeString = "AZTEC"
  117. case AVMetadataObject.ObjectType.code39:
  118. typeString = "CODE_39"
  119. case AVMetadataObject.ObjectType.code93:
  120. typeString = "CODE_93"
  121. case AVMetadataObject.ObjectType.code128:
  122. typeString = "CODE_128"
  123. case AVMetadataObject.ObjectType.dataMatrix:
  124. typeString = "DATA_MATRIX"
  125. case AVMetadataObject.ObjectType.ean8:
  126. typeString = "EAN_8"
  127. case AVMetadataObject.ObjectType.ean13:
  128. typeString = "EAN_13"
  129. case AVMetadataObject.ObjectType.itf14:
  130. typeString = "ITF"
  131. case AVMetadataObject.ObjectType.pdf417:
  132. typeString = "PDF_417"
  133. case AVMetadataObject.ObjectType.qr:
  134. typeString = "QR_CODE"
  135. case AVMetadataObject.ObjectType.upce:
  136. typeString = "UPC_E"
  137. default:
  138. return
  139. }
  140. guard let stringValue = code.stringValue else { continue }
  141. let result = ["code": stringValue, "type": typeString]
  142. if allowedBarcodeTypes.count == 0 || allowedBarcodeTypes.contains(code.type) {
  143. self?.channel.invokeMethod("onRecognizeQR", arguments: result)
  144. }
  145. }
  146. }
  147. })
  148. } catch {
  149. let error = FlutterError(code: "unknown-error", message: "Unable to start scanning", details: nil)
  150. return result(error)
  151. }
  152. } else {
  153. let error = FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil)
  154. result(error)
  155. }
  156. })
  157. }
  158. func stopCamera(_ result: @escaping FlutterResult) {
  159. if let sc: MTBBarcodeScanner = self.scanner {
  160. if sc.isScanning() {
  161. sc.stopScanning()
  162. }
  163. }
  164. }
  165. func getCameraInfo(_ result: @escaping FlutterResult) {
  166. result(self.cameraFacing.rawValue)
  167. }
  168. func flipCamera(_ result: @escaping FlutterResult) {
  169. if let sc: MTBBarcodeScanner = self.scanner {
  170. if sc.hasOppositeCamera() {
  171. sc.flipCamera()
  172. self.cameraFacing = sc.camera
  173. }
  174. return result(sc.camera.rawValue)
  175. }
  176. return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil))
  177. }
  178. func getFlashInfo(_ result: @escaping FlutterResult) {
  179. if let sc: MTBBarcodeScanner = self.scanner {
  180. result(sc.torchMode.rawValue != 0)
  181. } else {
  182. let error = FlutterError(code: "cameraInformationError", message: "Could not get flash information", details: nil)
  183. result(error)
  184. }
  185. }
  186. func toggleFlash(_ result: @escaping FlutterResult){
  187. if let sc: MTBBarcodeScanner = self.scanner {
  188. if sc.hasTorch() {
  189. sc.toggleTorch()
  190. return result(sc.torchMode == MTBTorchMode(rawValue: 1))
  191. }
  192. return result(FlutterError(code: "404", message: "This device doesn\'t support flash", details: nil))
  193. }
  194. return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil))
  195. }
  196. func pauseCamera(_ result: @escaping FlutterResult) {
  197. if let sc: MTBBarcodeScanner = self.scanner {
  198. if sc.isScanning() {
  199. sc.freezeCapture()
  200. }
  201. return result(true)
  202. }
  203. return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil))
  204. }
  205. func resumeCamera(_ result: @escaping FlutterResult) {
  206. if let sc: MTBBarcodeScanner = self.scanner {
  207. if !sc.isScanning() {
  208. sc.unfreezeCapture()
  209. }
  210. return result(true)
  211. }
  212. return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil))
  213. }
  214. func getSystemFeatures(_ result: @escaping FlutterResult) {
  215. if let sc: MTBBarcodeScanner = scanner {
  216. var hasBackCameraVar = false
  217. var hasFrontCameraVar = false
  218. let camera = sc.camera
  219. if(camera == MTBCamera(rawValue: 0)){
  220. hasBackCameraVar = true
  221. if sc.hasOppositeCamera() {
  222. hasFrontCameraVar = true
  223. }
  224. }else{
  225. hasFrontCameraVar = true
  226. if sc.hasOppositeCamera() {
  227. hasBackCameraVar = true
  228. }
  229. }
  230. return result([
  231. "hasFrontCamera": hasFrontCameraVar,
  232. "hasBackCamera": hasBackCameraVar,
  233. "hasFlash": sc.hasTorch(),
  234. "activeCamera": camera.rawValue
  235. ])
  236. }
  237. return result(FlutterError(code: "404", message: nil, details: nil))
  238. }
  239. }