Je viens donc de prendre en charge un projet iOS en tant que leur premier développement interne, où précédemment cette application avait été développée par une agence.QR Code Scanning ne fonctionne pas
L'une des caractéristiques de l'application est qu'elle a besoin de scanner les codes QR - par l'aspect du code que les développeurs précédents ont suivi this tutoriel sur AppCoda pour mettre en œuvre le scan QR. Tout semble bien et je ne vois rien de mal avec le code mais ça ne marche pas.
J'ai également téléchargé le tutoriel terminé et cela a fonctionné lorsque j'ai essayé le scan QR. J'ai également essayé de copier et coller chaque ligne pour qu'elle soit identique au tutoriel de travail mais pas de chance. Je me suis arraché les cheveux en essayant de comprendre pourquoi cela ne fonctionne pas.
Toute aide est très appréciée!
enum ScanState : Int {
case newDevice = 1
case resetDevice = 2
case replaceDevice = 3
}
class QRScannerViewController: BaseViewController,AVCaptureMetadataOutputObjectsDelegate {
@IBOutlet var scanZoneView: UIView!
@IBOutlet var scannerVIew: UIView!
@IBOutlet var scanInfoLabel: UILabel!
var capturedQR: String? = nil
var captureSession:AVCaptureSession?
var videoPreviewLayer:AVCaptureVideoPreviewLayer?
var qrCodeFrameView:UIView?
let supportedBarCodes = [AVMetadataObject.ObjectType.qr, AVMetadataObject.ObjectType.code128, AVMetadataObject.ObjectType.code39, AVMetadataObject.ObjectType.code93, AVMetadataObject.ObjectType.upce, AVMetadataObject.ObjectType.pdf417, AVMetadataObject.ObjectType.ean13, AVMetadataObject.ObjectType.aztec]
var type = "leg scan"
var device:Device?
var state:ScanState = .newDevice
override func viewDidLoad() {
super.viewDidLoad()
scanInfoLabel.text = "Scan your existing\nleg QR code"
self.navigationController?.navigationBar.dark()
//self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.setNavigationBarHidden(false, animated: true)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
#if NOHARDWARE
moveToNextViewController()
#else
initiateCapture()
#endif
}
func initiateCapture() {
let captureDevice = AVCaptureDevice.default(for: AVMediaType.video)
// Get an instance of the AVCaptureDeviceInput class using the previous device object.
var error:NSError?
let input: AnyObject!
do {
input = try AVCaptureDeviceInput(device: captureDevice!) as AVCaptureDeviceInput
} catch let error1 as NSError {
error = error1
input = nil
} catch _ {
input = nil
}
if (error != nil) {
// If any error occurs, simply log the description of it and don't continue any more.
print("\(error?.localizedDescription)")
return
}
// Initialize the captureSession object.
captureSession = AVCaptureSession()
// Set the input device on the capture session.
captureSession?.addInput(input as! AVCaptureInput)
// Initialize a AVCaptureMetadataOutput object and set it as the output device to the capture session.
let captureMetadataOutput = AVCaptureMetadataOutput()
captureSession?.addOutput(captureMetadataOutput)
// Set delegate and use the default dispatch queue to execute the call back
captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
captureMetadataOutput.metadataObjectTypes = supportedBarCodes
// Initialize the video preview layer and add it as a sublayer to the viewPreview view's layer.
videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession!)
videoPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
videoPreviewLayer?.frame = scannerVIew.layer.bounds
scannerVIew.layer.addSublayer(videoPreviewLayer!)
// Start video capture.
captureSession?.startRunning()
// Initialize QR Code Frame to highlight the QR code
qrCodeFrameView = UIView()
qrCodeFrameView?.layer.borderColor = UIColor.green.cgColor
qrCodeFrameView?.layer.borderWidth = 2
scannerVIew.addSubview(qrCodeFrameView!)
scannerVIew.bringSubview(toFront: qrCodeFrameView!)
//qrCapturedLabel.text = "No QR code is detected"
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func metadataOutput(captureOutput: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
// Check if the metadataObjects array is not nil and it contains at least one object.
if metadataObjects == nil || metadataObjects.count == 0 {
qrCodeFrameView?.frame = CGRect.zero
return
}
// Get the metadata object.
let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
// Here we use filter method to check if the type of metadataObj is supported
// Instead of hardcoding the AVMetadataObjectTypeQRCode, we check if the type
// can be found in the array of supported bar codes.
if supportedBarCodes.filter({ $0 == metadataObj.type }).count > 0 {
// If the found metadata is equal to the QR code metadata then update the status label's text and set the bounds
let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj as AVMetadataMachineReadableCodeObject) as! AVMetadataMachineReadableCodeObject
let intersectionRect = barCodeObject.bounds.intersection(self.scanZoneView.frame)
if !intersectionRect.isNull &&
(intersectionRect.size.width * intersectionRect.size.height) > self.scanZoneView.bounds.width * self.scanZoneView.bounds.height/7 {
qrCodeFrameView?.frame = barCodeObject.bounds
if process(metadataObj.stringValue!) {
captureSession?.stopRunning()
}
}
}
}
@IBAction func didTapCancel(_ sender: AnyObject) {
self.dismiss(animated: true, completion: nil)
}
}
extension QRScannerViewController {
func process(_ scanText : String) -> Bool {
var legCode : String
let codeComponents = scanText.components(separatedBy: ";")
if codeComponents.count > 0 {
legCode = codeComponents[0]
} else {
// Invalid number of parameters seperated by a ;
return false
}
// TODO Validate the LEG to LEG-XXXXX
if legCode.hasPrefix("LEG-") {
let delta: Int64 = 1 * Int64(NSEC_PER_SEC)
let time = DispatchTime.now() + Double(delta)/Double(NSEC_PER_SEC)
DispatchQueue.main.asyncAfter(deadline: time, execute: {
switch self.state {
case .resetDevice:
let realm = try! Realm()
let deviceList = realm.objects(Device.self)
let lc = legCode
self.device = deviceList.filter("legCode = %@", lc).first
if self.device == nil {
// TODO Error message: Device not associated with LEG
let vc = ErrorViewController.createErrorViewController(.DeviceNotFound)
self.present(vc, animated: true, completion: nil)
return
}
self.moveToNextViewController()
default:
self.presentingViewController?.dismiss(animated: true, completion: nil)
}
});
return true
}
return false
}
func moveToNextViewController() {
let inspectionStoryboard = UIStoryboard(name: "Impact", bundle: nil)
if let resetVC = inspectionStoryboard.instantiateViewController(withIdentifier: ImpactDetectionViewController.storyboardID) as? ImpactDetectionViewController {
resetVC.device = device
// TODO Pass the impact type across too when the G2 API is set
self.navigationController?.pushViewController(resetVC, animated: false)
}
}
@IBAction func cancelToVC(_ segue: UIStoryboardSegue) { }
}
EDIT
En ne fonctionne pas, je veux dire le délégué pour AVCaptureMetadataOutputObjectsDelegate
est jamais appelé il ne semble jamais être détecter un code QR. Dans le tutoriel AppCoda, il recouvre un carré vert où il détecte le code QR, mais cela ne se produit jamais lorsque je mets ce code dans cette application.
La caméra est en cours d'exécution mais les codes QR ne sont jamais détectés.
Je pense qu'il est normal de partager une bibliothèque si je poste un commentaire, je me sers de ce pod pour la vie facile, il suffit Je voudrais suggérer: https://github.com/yannickl/QRCodeReader.swift – Glenn
Merci Glenn, j'ai regardé ça mais quand j'ai installé le pod il y avait 11 erreurs venant du framework alors j'ai décidé que ça serait juste plus facile cette mise en œuvre fonctionne –
Pouvez-vous nous donner plus de détails? Que se passe-t-il lorsque vous exécutez ce code? La caméra fonctionne-t-elle? Pouvez-vous voir les cadres de vue de la caméra? Avez-vous essayé de vérifier avec le point d'arrêt à''didOutput metadataObject'? – Bluewings