Reputation: 11
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
}
}
Upvotes: 0
Views: 580
Reputation: 26
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.
Upvotes: 1
Reputation: 2230
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"]
}
}
Upvotes: 0