Julian Silvestri
Julian Silvestri

Reputation: 2027

Custom Barcode scanner, cannot pass back scanned data

I am having trouble passing back data that is scanned by my custom barcode scanner. The data is read successfully and I am able to assign the value to a variable. But I cannot pass the data back to the previous view controller to populate a text view.

I am using this below to pass to my barcode VC to store the data inside it

var barcodeScanData: String = ""

I am using prepare for segue below to

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "BarcodeScanVC" {
        let desitnationVC = segue.destination as! BarcodeScanVC
        desitnationVC.xyz = barcodeScanData
    }
}

Below here is where I am attempting to send back the data from my custom barcode scanner

var xyz: String = ""

func launchApp(barcodeScan: String) {

        if presentedViewController != nil {
            return
        }

        let alertPrompt = UIAlertController(title: "Barcode Found", message: "\(barcodeScan)", preferredStyle: .actionSheet)
        let confirmAction = UIAlertAction(title: "Confirm", style: UIAlertAction.Style.default, handler: { (action) -> Void in
            let barcodeData = PartsVCDetail()
            self.xyz = barcodeScan
            barcodeData.barcodeScanData = self.xyz
            print(self.xyz, "This is what I am sending")
            print(barcodeData.barcodeScanData, "This is what I am sending it TO" )


            self.navigationController?.popViewController(animated: true)
        })

        let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertAction.Style.cancel, handler: nil)

        alertPrompt.addAction(confirmAction)
        alertPrompt.addAction(cancelAction)

        present(alertPrompt, animated: true, completion: nil)
    }

The two print lines

print(self.waybill, "This is what I am sending")
print(barcodeData.barcodeScanData, "This is what I am sending it TO"

Show me the correct scan data, however, when I use the last line below:

self.navigationController?.popViewController(animated: true)

The data is lost and I see an empty value in my viewDidAppear on the first view controller:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(true)
    print(barcodeScanData, "This is empty but it shouldnt be")
    dataFromBarcodeScanner.text = barcodeScanData
}

What am I missing ?

Upvotes: 0

Views: 72

Answers (1)

Paulw11
Paulw11

Reputation: 114773

With this code let barcodeData = PartsVCDetail() you are creating a new instance of PartsVCDetail and then setting the property of that instance. As soon as the action ends this instance will be deallocated and you will return to the previous view controller via popViewController.

A common solution to your requirement is a delegation pattern.

  • You declare a protocol for your delegate to implement
  • You have the original view controller implement this delegate protocol
  • You have the original view controller set itself as the second view controller's delegate
  • The second view controller can invoke the delegate method to pass the data back

Protocol

protocol BarcodeScanDelegate {
    func didScan(barcodeData: String)
}

PartsVCDetail

class PartsVCDetail: UIViewController, BarcodeScanDelegate {

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let desitnationVC = segue.destination as? BarcodeScanVC {
            desitnationVC.delegate = self
        }
    }

    func didScan(barcodeData: String) {
        self.barcodeScanData = barcodeData
    }
}

BarcodeScanVC

var delegate: BarcodeScanDelegate?

func launchApp(barcodeScan: String) {

    guard presentedViewController == nil else {
        return
    }

    let alertPrompt = UIAlertController(title: "Barcode Found", message: "\(barcodeScan)", preferredStyle: .actionSheet)
    let confirmAction = UIAlertAction(title: "Confirm", style: UIAlertAction.Style.default, handler: { (action) -> Void in
        self.delegate?.didScan(barcodeData: self.xyz)
        self.navigationController?.popViewController(animated: true)
    })

    let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertAction.Style.cancel, handler: nil)

    alertPrompt.addAction(confirmAction)
    alertPrompt.addAction(cancelAction)

    present(alertPrompt, animated: true, completion: nil)
}

Upvotes: 1

Related Questions