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 ?
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.
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)
}