0

Tried to send data from one view controller (from an alamofire request) to the next view controller in a navigation controller.

I tried to this with a delegate, but I do not get it working. I allready know this is not the way, but i need to find a solution to get it working.

See below for the code, from view controller that sends variabels:

protocol SendDataToScanInfo {
    func sendData (vendorname01 : String,  productname01: String, productstatus01: String, productdescription01: String)
}

class ScanController: UIViewController, AVCaptureMetadataOutputObjectsDelegate, CLLocationManagerDelegate{

var delegate:SendDataToScanInfo?

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) { 

Alamofire.request(URL_SCAN_ID, method: .post, parameters: ScanParameters, encoding: JSONEncoding.default) .responseJSON
                {

                    response in

                    //printing response
                    print(response.request!)
                    print(response.response!)
                    print(response.data!)
                    print(response.result)
                    print(response.error)

                    //getting the json value from the server
                    let value = response.result.value
                    print(value!)
                    let json = JSON(value!)

                    let productdesc0:JSON = json["productdesc"]
                    let productdescString = productdesc0.string


                    let productname0:JSON = json["productname"]
                    let productnameString = productname0.string


                    let tagstate0:JSON = json["tagstate"]
                    let tagstateString = tagstate0.string


                    let vendorname0:JSON = json["vendorname"]
                    let vendornameString = vendorname0.string


                    //self.performSegue(withIdentifier: "ScanInfo", sender: productdescString)
                    self.delegate?.sendData(vendorname01: vendornameString!, productname01: productnameString!, productstatus01: tagstateString!, productdescription01: productdescString!)




                    print(vendornameString)
                }
            if code != nil
            {
                let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
                let destination = mainStoryboard.instantiateViewController(withIdentifier: "ScanInfo")
                navigationController?.pushViewController(destination, animated: true)
            }

            captureSession.stopRunning();
            //self.dismiss(animated: true, completion: nil)
        }
    }
}

Next Viewcontroller should receive it:

class ScanInfoViewController: UIViewController, SendDataToScanInfo {



    @IBOutlet weak var Vendor: UILabel!
    @IBOutlet weak var VendorScan: UILabel!
    @IBOutlet weak var Product: UILabel!
    @IBOutlet weak var ProductScan: UILabel!
    @IBOutlet weak var Status: UILabel!
    @IBOutlet weak var DescriptionScan: UILabel!
    @IBOutlet weak var Description: UILabel!
    @IBOutlet weak var StatusScan: UILabel!



    override func viewDidLoad() {
        super.viewDidLoad()
        DescriptionScan.text = descriptionBLA
        print("jddjd", descriptionBLA)
        let URL_SCAN_INFO = "http://makeitrain.get-legit.com:8998/checktag"

        // Do any additional setup after loading the view.

    }


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func sendData(vendorname01: String, productname01: String, productstatus01: String, productdescription01: String) {
        VendorScan.text = vendorname01
        ProductScan.text = productname01
        DescriptionScan.text = productdescription01
        StatusScan.text = productstatus01
        print("MMMM", StatusScan.text)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "ScanInfo" {
            let sendingVC: ScanController = segue.destination as! ScanController
            sendingVC.delegate = self
        }
    }
}

I hope some one can help me!

williej926
  • 123
  • 10
R. Breg
  • 9
  • 4
  • You could inject the service call. Isn't the info controller the destination? If so why are you overriding the segue method in it? – Swift Rabbit Aug 01 '17 at 21:14
  • Possible duplicate of [Passing Data between View Controllers](https://stackoverflow.com/questions/5210535/passing-data-between-view-controllers) – Rajat Khare Aug 01 '17 at 21:18
  • easiest way to pass data between view controller I found is with app delegate try Checking my answer on this link maybe helpful for you https://stackoverflow.com/questions/44877352/passing-data-from-one-view-controller-to-another/44877517#44877517 – iOS Geek Aug 02 '17 at 05:15

3 Answers3

0

To pass data forward, like williej926 said, segues are the way to go. To pass data forward from one viewcontroller to another, you need to create a segue between these two viewcontrollers, and give the segue an identifier if there is more than one segue in your project that you are using to pass data, then this is a must. In your first view controller's class you should create a prepareForSegue method by using the one built-in. In that prepareForSegue method, you write if the segue's identifier is equal to the one that you have set in your storyboard. In that if statement, you need to tell this viewcontroller what your segue's destination is. To do that write let destination = segue.destination as! nextViewControllerClass. To access variables and set them in your second viewcontroller, write destination.variableName = thisVariableName. Here is an example showing you what this looks like purely in code.

In First View Controller's class

class FirstViewController: UIViewController {

var thisString: String?

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if let identifier = segue.identifier {
                if(identifier == "secondViewController") {
                    let destination = segue.destination as! SecondViewController//SecondViewController is second view controller's class
                    destination.myString = thisString
            }
        }
    }
}

Second View Controller's Class

class SecondViewController: UIViewController {
     var myString: String?//this will equal to thisString in FirstViewController
}
Rajat Khare
  • 522
  • 8
  • 26
0

I wrote an answer about this not too long ago :

One the simpler way to pass info from one VC to another is either through an initiliazer, or through a variable that you set before presenting the second VC.

The secone method would have you go through a delegate, mainly when passing data BACK to the initial VC. Either way, you'd need a setup similar to this:

class LoggedInVCViewController : UIViewController {

    var info : String? {
       didSet {
          if let newInfo = self.info {
             //do what ever you need to do here
          }
       }
    }

    override viewDidLoad() {
       super.viewDidLoad()

    }

}

func presentLoggedInScreen(yourInfo: String) { 
   let stroyboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil) 
   let loggedInVC:LoggedInVCViewController = 
   storyboard.instantiateViewController(withIdentifier: "loggedInVC") as! 
   LoggedInVCViewController 
   loggedInVC.info = yourInfo
   self.present(loggedInVC, animated: true, completion: nil) 
}
class LoggedInVCViewController : UIViewController {

    var info : Any? {
        get {
            if let this = self.info {
                return this
            } else {
                return nil
            }
        } set {
            if let new = newValue {
                //
            }
        }
    }

    init(info: Any?) {
        //This first line is key, it also calls viewDidLoad() internally, so don't re-write viewDidLoad() here!!
        super.init(nibName: nil, bundle: nil)

        if let newInfo = info {
            //here we check info for whatever you pass to it
            self.info = newInfo
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

Which is then used :

func presentLoggedInScreen(yourInfo: String) {
        let loggedInVC = LoggedInVCViewController(info: yourInfo)
        self.present(loggedInVC, animated: true, completion: nil)
}

Or if you're using the variable approach:

func presentLoggedInScreen(yourInfo: String) {
        let loggedInVC = LoggedInVCViewController() 
        loggedInVC.info = yourInfo
        self.present(loggedInVC, animated: true, completion: nil)
}

I also go over, and link to other post which talk about the caveats of using Storyboards, and custom initializers to pass on data. I'd read over them as well!

jlmurph
  • 1,050
  • 8
  • 17
-1

The best way to do this is by using a segue. Connect a segue between the controllers and in the prepareForSegue you add a variable that represents the controller you are segueing to like so: let viewController = segue.destination as! viewController. Now you can access and change variables inside viewController using viewController.variable.

williej926
  • 123
  • 10