0

I'm trying to pass data using a prepare(for segue:) function but it's showing nil in the second VC. Am I doing anything wrong?

class ViewController: UIViewController {

    var first : [String] = []

    @IBOutlet weak var passField: UITextField!
    @IBOutlet weak var userID: UITextField!

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

    @IBAction func login(_ sender: Any) {
        let user : String = self.userID.text!
        let password : String = self.passField.text!

        if user != "" && password != "" {
            let postString = ["username":user, “password”: password]
            var request = URLRequest(url:URL(string:"http://mydomainhere.com/api/login")!)
            request.httpMethod = "POST"
            request.httpBody = try! JSONSerialization.data(withJSONObject: postString, options:.prettyPrinted)
            let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
                if error != nil {
                    print("error=\(error)")
                    return
                }

                do {
                    if let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any] {
                        let firstName = json["first_name"] as? String
                        let lastName = json["last_name"] as? String
                        self.first.append(firstName!) //putting into Array
                        self.performSegue(withIdentifier: "loginSegue", sender: self)
                    }
                } catch {
                    print(error)
                }
            }
        }
    }

    // data transfer to another controller
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "loginSegue" {
            let secondController = segue.destination as? SecondVC
            secondController?.name = first //passing to next VC   //* here having the issue its not passing the data to next VC
            print(first)    // here first is printing perfectly
        }
    } 
}


// second View Controller
class SecondVC: UIViewController {

    var menu_vc : MenuViewController!
    var name : [String]?    // passing to this Array

    override func viewDidLoad() {
        super.viewDidLoad()
        print(name)    // here printing nil 
    }
}
5
  • Set a breakpoint in prepareForSegue and step though to see what is happening. The view controller downcast may be failing. Commented Jun 4, 2017 at 5:10
  • @Paulw11 Thanks for responding but I am not getting you. Can you please suggest me with some code What I need to do actually. Commented Jun 4, 2017 at 5:18
  • I can't suggest code. The code you have looks generally correct. Learn how to use the very powerful debugger that is built in to Xcode to step through your app and see what it is doing. Commented Jun 4, 2017 at 5:19
  • Is the second VC embedded in a UINavigationController? Commented Jun 4, 2017 at 7:00
  • Code formatting and grammar and readability and title Commented Jun 5, 2017 at 19:29

2 Answers 2

1

As suggested by @Sweeper, it could very well be that your destination view controller is embedded in a UINavigationViewController, hence your segue.destination is in fact a UINavigationViewController, not a SecondVC.

You can try this code:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    var destinationViewController = segue.destination
    if let navigationController = destinationViewController as? UINavigationController {
        destinationViewController = navigationController.visibleViewController ?? destinationViewController
    }
    if let secondController = destinationViewController as? SecondVC {
        secondController?.name = first
    }
}

Of course the first four lines of code could be refactored in an appropriate function (even better if in an extension of UIViewController).

If that solves the problem, you can watch cs193p Stanford iOS course for further details. In particular watch https://www.youtube.com/watch?v=HQrXM2zUPvY&index=6&list=PLPA-ayBrweUz32NSgNZdl0_QISw-f12Ai starting from the 30:20 mark.

Sign up to request clarification or add additional context in comments.

Comments

0

Everything seems perfect with the below snippet

var first : [String] = []

@IBAction func btnTapped(_ sender: Any) {
    let firstName = "iOS Geek"
    self.first.append(firstName)

    self.performSegue(withIdentifier: "MovetoSecVC", sender: self)
}


override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "MovetoSecVC"{

        let secVC = segue.destination as! SecondVC
        secVC.name = first
        print(first) // it'll print here ["iOS Geek"]
    }
}

// Your Second View Controller

class SecondVC: UIViewController {

var menu_vc : MenuViewController!
var name : [String]?    // passing to this Array

override func viewDidLoad() {
    super.viewDidLoad()

    print(name!)    // it'll print here ["iOS Geek"]
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.