The QR Code Scanner package for Appeto SDK.
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

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