The QR Code Scanner package for Appeto SDK.
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 
 
 

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