2015-07-01 19 views
7

Ho la scansione dei codici a barre che funziona nella mia app. Una volta rilevato il codice a barre, interrompo la sessione di acquisizione per consentire l'elaborazione del codice a barre. Tuttavia, dopo aver elaborato il codice a barre, desidero che il controller di scansione rimanga alzato e che il successivo codice a barre venga scansionato. Avevo pensato che l'avvio della sessione di cattura (startRunning()) avrebbe funzionato, ma l'immagine rimane bloccata. Come posso avviare nuovamente la sessione di acquisizione?Lettura codici a barre iOS Swift

+0

codice a barre scaner in rapida 3.0: https://iosdevcenters.blogspot.com/2017/09/building-barcode-and-qr- code-reader-in.html –

risposta

11

per fermare l'uso di questo codice sessione

  self.session.stopRunning() 

Per cominciare lo saremo ancora, utilizzare questo codice

self.session.startRunning() 

Ecco tutto il codice per implementare uno scanner di codice a barre ...

import UIKit 
import AVFoundation 


class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate { 

    let session   : AVCaptureSession = AVCaptureSession() 
    var previewLayer : AVCaptureVideoPreviewLayer! 
    var highlightView : UIView = UIView() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // Allow the view to resize freely 
     self.highlightView.autoresizingMask = UIViewAutoresizing.FlexibleTopMargin | 
      UIViewAutoresizing.FlexibleBottomMargin | 
      UIViewAutoresizing.FlexibleLeftMargin | 
      UIViewAutoresizing.FlexibleRightMargin 

     // Select the color you want for the completed scan reticle 
     self.highlightView.layer.borderColor = UIColor.greenColor().CGColor 
     self.highlightView.layer.borderWidth = 3 

     // Add it to our controller's view as a subview. 
     self.view.addSubview(self.highlightView) 


     // For the sake of discussion this is the camera 
     let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo) 

     // Create a nilable NSError to hand off to the next method. 
     // Make sure to use the "var" keyword and not "let" 
     var error : NSError? = nil 


     let input : AVCaptureDeviceInput? = AVCaptureDeviceInput.deviceInputWithDevice(device, error: &error) as? AVCaptureDeviceInput 

     // If our input is not nil then add it to the session, otherwise we're kind of done! 
     if input != nil { 
      session.addInput(input) 
     } 
     else { 
      // This is fine for a demo, do something real with this in your app. :) 
      println(error) 
     } 

     let output = AVCaptureMetadataOutput() 
     output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue()) 
     session.addOutput(output) 
     output.metadataObjectTypes = output.availableMetadataObjectTypes 


     previewLayer = AVCaptureVideoPreviewLayer.layerWithSession(session) as! AVCaptureVideoPreviewLayer 
     previewLayer.frame = self.view.bounds 
     previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill 
     self.view.layer.addSublayer(previewLayer) 

     // Start the scanner. You'll have to end it yourself later. 
     session.startRunning() 

    } 

    // This is called when we find a known barcode type with the camera. 
    func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) { 

     var highlightViewRect = CGRectZero 

     var barCodeObject : AVMetadataObject! 

     var detectionString : String! 

     let barCodeTypes = [AVMetadataObjectTypeUPCECode, 
      AVMetadataObjectTypeCode39Code, 
      AVMetadataObjectTypeCode39Mod43Code, 
      AVMetadataObjectTypeEAN13Code, 
      AVMetadataObjectTypeEAN8Code, 
      AVMetadataObjectTypeCode93Code, 
      AVMetadataObjectTypeCode128Code, 
      AVMetadataObjectTypePDF417Code, 
      AVMetadataObjectTypeQRCode, 
      AVMetadataObjectTypeAztecCode 
     ] 


     // The scanner is capable of capturing multiple 2-dimensional barcodes in one scan. 
     for metadata in metadataObjects { 

      for barcodeType in barCodeTypes { 

       if metadata.type == barcodeType { 
        barCodeObject = self.previewLayer.transformedMetadataObjectForMetadataObject(metadata as! AVMetadataMachineReadableCodeObject) 

        highlightViewRect = barCodeObject.bounds 

        detectionString = (metadata as! AVMetadataMachineReadableCodeObject).stringValue 

        self.session.stopRunning() 

self.alert(detectionString) 
        break 
       } 

      } 
     } 

     println(detectionString) 
     self.highlightView.frame = highlightViewRect 
     self.view.bringSubviewToFront(self.highlightView) 

    } 



    func alert(Code: String){ 
     let actionSheet:UIAlertController = UIAlertController(title: "Barcode", message: "\(Code)", preferredStyle: UIAlertControllerStyle.Alert) 

     // for alert add .Alert instead of .Action Sheet 


     // start copy 

     let firstAlertAction:UIAlertAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: 


      { 
       (alertAction:UIAlertAction!) in 


       // action when pressed 

       self.session.startRunning() 




     }) 

     actionSheet.addAction(firstAlertAction) 

     // end copy 






     self.presentViewController(actionSheet, animated: true, completion: nil) 

    } 



} 
+0

Se ciò ha funzionato, non dimenticare di contrassegnare questa risposta come corretta. –

+0

Stavo facendo praticamente la stessa cosa ma avevo due righe di codice scambiate. Stavo inviando la stringa del risultato al mio gestore e poi interrompendo la sessione. Non si riavvierebbe. Se ho interrotto la sessione prima di inviare i risultati al mio gestore, ha funzionato. –

+0

Aggiunta la versione Swift 3 qui: http://stackoverflow.com/a/41512546/2108523 – mkhoshpour

10

modificato il codice sopra per swift 2.0:

import UIKit 
import AVFoundation 


class BarCodeViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate { 

    let session   : AVCaptureSession = AVCaptureSession() 
    var previewLayer : AVCaptureVideoPreviewLayer! 
    @IBOutlet weak var highlightView: UIView! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // Allow the view to resize freely 
//  self.highlightView.autoresizingMask = UIViewAutoresizing.FlexibleTopMargin | 
//   UIViewAutoresizing.FlexibleBottomMargin | 
//   UIViewAutoresizing.FlexibleLeftMargin | 
//   UIViewAutoresizing.FlexibleRightMargin 
//   
     // Select the color you want for the completed scan reticle 
     self.highlightView.layer.borderColor = UIColor.greenColor().CGColor 
     self.highlightView.layer.borderWidth = 3 

     // Add it to our controller's view as a subview. 
     self.view.addSubview(self.highlightView) 


     // For the sake of discussion this is the camera 
     let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo) 

     // Create a nilable NSError to hand off to the next method. 
     // Make sure to use the "var" keyword and not "let" 
     var error : NSError? = nil 
     var input: AVCaptureDeviceInput = AVCaptureDeviceInput() 
     do { 
      input = try AVCaptureDeviceInput(device: device) as AVCaptureDeviceInput 
     } catch let myJSONError { 
      print(myJSONError) 
     } 

     // If our input is not nil then add it to the session, otherwise we're kind of done! 
     if input != AVCaptureDeviceInput() { 
      session.addInput(input) 
     } 
     else { 
      // This is fine for a demo, do something real with this in your app. :) 
      print(error) 
     } 

     let output = AVCaptureMetadataOutput() 
     output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue()) 
     session.addOutput(output) 
     output.metadataObjectTypes = output.availableMetadataObjectTypes 


     previewLayer = AVCaptureVideoPreviewLayer(session: session) 
     previewLayer.frame = self.view.bounds 
     previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill 
     self.view.layer.addSublayer(previewLayer) 

     // Start the scanner. You'll have to end it yourself later. 
     session.startRunning() 

    } 

    // This is called when we find a known barcode type with the camera. 
    func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) { 

     var highlightViewRect = CGRectZero 

     var barCodeObject : AVMetadataObject! 

     var detectionString : String! 

     let barCodeTypes = [AVMetadataObjectTypeUPCECode, 
      AVMetadataObjectTypeCode39Code, 
      AVMetadataObjectTypeCode39Mod43Code, 
      AVMetadataObjectTypeEAN13Code, 
      AVMetadataObjectTypeEAN8Code, 
      AVMetadataObjectTypeCode93Code, 
      AVMetadataObjectTypeCode128Code, 
      AVMetadataObjectTypePDF417Code, 
      AVMetadataObjectTypeQRCode, 
      AVMetadataObjectTypeAztecCode 
     ] 


     // The scanner is capable of capturing multiple 2-dimensional barcodes in one scan. 
     for metadata in metadataObjects { 

      for barcodeType in barCodeTypes { 

       if metadata.type == barcodeType { 
        barCodeObject = self.previewLayer.transformedMetadataObjectForMetadataObject(metadata as! AVMetadataMachineReadableCodeObject) 

        highlightViewRect = barCodeObject.bounds 

        detectionString = (metadata as! AVMetadataMachineReadableCodeObject).stringValue 

        self.session.stopRunning() 

        self.alert(detectionString) 
        break 
       } 

      } 
     } 

     print(detectionString) 
     self.highlightView.frame = highlightViewRect 
     self.view.bringSubviewToFront(self.highlightView) 

    } 



    func alert(Code: String){ 
     let actionSheet:UIAlertController = UIAlertController(title: "Barcode", message: "\(Code)", preferredStyle: UIAlertControllerStyle.Alert) 

     // for alert add .Alert instead of .Action Sheet 


     // start copy 

     let firstAlertAction:UIAlertAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: 


      { 
       (alertAction:UIAlertAction!) in 


       // action when pressed 

       self.session.startRunning() 




     }) 

     actionSheet.addAction(firstAlertAction) 

     // end copy 






     self.presentViewController(actionSheet, animated: true, completion: nil) 

    } 



} 
+0

Questo è fantastico, grazie! –

3

Swift 3.0 versione:

import UIKit 
import AVFoundation 


class BarCodeViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate { 


let session   : AVCaptureSession = AVCaptureSession() 
var previewLayer : AVCaptureVideoPreviewLayer! 
@IBOutlet weak var highlightView: UIView! 

override func viewDidLoad() { 
    super.viewDidLoad() 

    // Allow the view to resize freely 
    //  self.highlightView.autoresizingMask = UIViewAutoresizing.FlexibleTopMargin | 
    //   UIViewAutoresizing.FlexibleBottomMargin | 
    //   UIViewAutoresizing.FlexibleLeftMargin | 
    //   UIViewAutoresizing.FlexibleRightMargin 
    // 
    // Select the color you want for the completed scan reticle 
    self.highlightView.layer.borderColor = UIColor.green.cgColor 
    self.highlightView.layer.borderWidth = 3 

    // Add it to our controller's view as a subview. 
    self.view.addSubview(self.highlightView) 


    // For the sake of discussion this is the camera 
    let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) 

    // Create a nilable NSError to hand off to the next method. 
    // Make sure to use the "var" keyword and not "let" 
    var error : NSError? = nil 
    var input: AVCaptureDeviceInput = AVCaptureDeviceInput() 
    do { 
     input = try AVCaptureDeviceInput(device: device) as AVCaptureDeviceInput 
    } catch let myJSONError { 
     print(myJSONError) 
    } 

    // If our input is not nil then add it to the session, otherwise we're kind of done! 
    if input != AVCaptureDeviceInput() { 
     session.addInput(input) 
    } 
    else { 
     // This is fine for a demo, do something real with this in your app. :) 
     print(error!) 
    } 

    let output = AVCaptureMetadataOutput() 
    output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main) 
    session.addOutput(output) 
    output.metadataObjectTypes = output.availableMetadataObjectTypes 


    previewLayer = AVCaptureVideoPreviewLayer(session: session) 
    previewLayer.frame = self.view.bounds 
    previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill 
    self.view.layer.addSublayer(previewLayer) 

    // Start the scanner. You'll have to end it yourself later. 
    session.startRunning() 

} 

// This is called when we find a known barcode type with the camera. 
@nonobjc func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) { 

    var highlightViewRect = CGRect() 

    var barCodeObject : AVMetadataObject! 

    var detectionString : String! 

    let barCodeTypes = [AVMetadataObjectTypeUPCECode, 
         AVMetadataObjectTypeCode39Code, 
         AVMetadataObjectTypeCode39Mod43Code, 
         AVMetadataObjectTypeEAN13Code, 
         AVMetadataObjectTypeEAN8Code, 
         AVMetadataObjectTypeCode93Code, 
         AVMetadataObjectTypeCode128Code, 
         AVMetadataObjectTypePDF417Code, 
         AVMetadataObjectTypeQRCode, 
         AVMetadataObjectTypeAztecCode 
    ] 


    // The scanner is capable of capturing multiple 2-dimensional barcodes in one scan. 
    for metadata in metadataObjects { 

     for barcodeType in barCodeTypes { 

      if metadata.type == barcodeType { 
       barCodeObject = self.previewLayer.transformedMetadataObject(for: metadata as! AVMetadataMachineReadableCodeObject) 

       highlightViewRect = barCodeObject.bounds 

       detectionString = (metadata as! AVMetadataMachineReadableCodeObject).stringValue 

       self.session.stopRunning() 

       self.alert(Code: detectionString) 
       break 
      } 

     } 
    } 

    print(detectionString) 
    self.highlightView.frame = highlightViewRect 
    self.view.bringSubview(toFront: self.highlightView) 

} 



func alert(Code: String){ 
    let actionSheet:UIAlertController = UIAlertController(title: "Barcode", message: "\(Code)", preferredStyle: UIAlertControllerStyle.alert) 

    // for alert add .Alert instead of .Action Sheet 


    // start copy 

    let firstAlertAction:UIAlertAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: 


     { 
      (alertAction:UIAlertAction!) in 


      // action when pressed 

      self.session.startRunning() 




    }) 

    actionSheet.addAction(firstAlertAction) 

    // end copy 






    self.present(actionSheet, animated: true, completion: nil) 

} 

}