0

I'm trying to show a new screen via a segue, labeled toConsoleScreen. I keep getting the error:

Receiver () has no segue with identifier 'toConsoleScreen'

I am 100% sure that my segue is labeled toConsolescreen, and the segue is connected in the Interface Builder.

The 'rootViewController' hasn't been touched, but I created a new UIViewController for the 2nd page called Console Screen, with a class of ConsoleViewController.

What am I doing wrong? It tells me it can't find the segue toConsoleScreen when it's obviously present.

I'm using:

self.performSegue(withIdentifier: "toConsoleScreen", sender: self)

from within the ViewController. I have tried deleting the segue and recreating it (using the 'show' setting), as well as running the Product -> Clean feature.

I should also add that I'm trying to call performSegue within a function inside of ViewController. This function is called from a separate Swift file. I'm somewhat new to Swift, so how can I make this possible?

Here is my current ViewController.Swift file:

import UIKit

class ViewController: UIViewController {

@IBOutlet var UserNameField: UITextField!
@IBOutlet var PasswordField: UITextField!

func successfulLogin(Username: String) {

    // Show next view \\

        self.performSegue(withIdentifier: "toConsoleScreen", sender: self)

}

override func viewDidLoad() {
    super.viewDidLoad()

    self.hideKeyboardWhenTappedAround()

    // Do any additional setup after loading the view, typically from a nib.
}

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

@IBAction func loginButton() {

            login(Username: UserNameField.text!, Password: PasswordField.text!)
}



}

And my Login.swift file:

    import Foundation
import UIKit



func login(Username: String, Password: String) {

    var request = URLRequest(url: URL(string: "web address")!)
    request.httpMethod = "POST"
    let postString = "action=login&username=\(Username)&password=\(Password)"
    request.httpBody = postString.data(using: .utf8)
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        guard let data = data, error == nil else {                                                 // check for fundamental networking error
        print("error=\(error)")
        return
    }

        if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {           // check for http errors
            print("statusCode should be 200, but is \(httpStatus.statusCode)")
            print("response = \(response)")
    }

        let responseString = String(data: data, encoding: .utf8)

        if responseString! == "success" {
            print("Good")

            // Send to new page \\


            ViewController().successfulLogin(Username: Username)
    }



        if responseString! == "fail" {

            print("failed")
            // Alert Error \\


        func alertPopup(title: String, message: String) {

            let alertController = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
            UIApplication.shared.keyWindow?.rootViewController?.present(alertController, animated: true, completion: nil)
            alertController.addAction(UIAlertAction(title: "Try Again", style: UIAlertActionStyle.default, handler:  nil))
            }

            // Add to main Queue \\
            OperationQueue.main.addOperation{
            alertPopup(title: "Error", message: "Invalid Login")
            }
    }


}
task.resume()



}
Rodia
  • 1,407
  • 8
  • 22
  • 29
szady
  • 125
  • 1
  • 1
  • 9
  • Are you calling this in `viewDidLoad`? – chengsam Feb 28 '17 at 03:47
  • Tried these many many solutions? If so, you should update your question to avoid a duplicate flag. http://stackoverflow.com/questions/33057818/receiver-has-no-segue-with-identifier-error-message http://stackoverflow.com/questions/20715462/receiver-viewcontroller-has-no-segue-with-identifier-addsegue http://stackoverflow.com/questions/31241877/receiver-has-no-segue-with-identifier http://stackoverflow.com/questions/29324132/receiver-viewcontroller-has-no-segue-with-identifier-showalerting http://stackoverflow.com/questions/25020866/receiver-has-no-segue-with-identifier-when-identifier-exists –  Feb 28 '17 at 03:50
  • Thanks. I've restated my question. – szady Feb 28 '17 at 04:04
  • You mentioned that this function is called from a seperate Swift file. Is that file a ViewController? – chengsam Feb 28 '17 at 04:08
  • I apologize. I have included all of my code now. – szady Feb 28 '17 at 04:18
  • Make sure that the `UIViewController` the segue is being performed from is set in the storyboard. – Brandon A Feb 28 '17 at 04:27
  • Possible duplicate of [Receiver has no segue with identifier error message](http://stackoverflow.com/questions/33057818/receiver-has-no-segue-with-identifier-error-message) – Harshal Valanda Feb 28 '17 at 04:32
  • Brandon, could you elaborate? How do I 'set' the `UIViewController` in the storyboard? The segue is attached to the `ViewController` that defaults on screen when you first open the `Main.Storyboard`. – szady Feb 28 '17 at 04:33
  • I've updated with code below, please check. – chengsam Feb 28 '17 at 05:40

1 Answers1

0

You shouldn't call the method like this:

ViewController().successfulLogin(Username: Username)

The above code will init a new instance of ViewController. You should use delegate pattern or completion handler to call the successfulLogin method.

Example of using completion handler:

In ViewController.swift:

@IBAction func loginButton() {
        login(Username: UserNameField.text!, Password: PasswordField.text!) { username in
            self.successfulLogin(Username: username)
        }
    }

In Login.swift:

func login(Username: String, Password: String, completion: @escaping (String) -> Void) {

    var request = URLRequest(url: URL(string: "web address")!)
    request.httpMethod = "POST"
    let postString = "action=login&username=\(Username)&password=\(Password)"
    request.httpBody = postString.data(using: .utf8)
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        guard let data = data, error == nil else {                                                 // check for fundamental networking error
        print("error=\(error)")
        return
    }

        if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {           // check for http errors
            print("statusCode should be 200, but is \(httpStatus.statusCode)")
            print("response = \(response)")
    }

        let responseString = String(data: data, encoding: .utf8)

        if responseString! == "success" {
            print("Good")

            // Send to new page \\


            completion(Username)
    }



        if responseString! == "fail" {

            print("failed")
            // Alert Error \\


        func alertPopup(title: String, message: String) {

            let alertController = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
            UIApplication.shared.keyWindow?.rootViewController?.present(alertController, animated: true, completion: nil)
            alertController.addAction(UIAlertAction(title: "Try Again", style: UIAlertActionStyle.default, handler:  nil))
            }

            // Add to main Queue \\
            OperationQueue.main.addOperation{
            alertPopup(title: "Error", message: "Invalid Login")
            }
    }


}
task.resume()



}
chengsam
  • 7,315
  • 6
  • 30
  • 38
  • Thank you! This is exactly what I've been trying to accomplish! Code worked flawlessly, minus one exception... I had to add `OperationQueue.main.addOperation` to the `performSegue` call. I owe you a coffee (or a beer if you prefer that instead...). – szady Feb 28 '17 at 22:36
  • Ok, so back to this again... Once the next view controller loads (ConsoleViewController), I have a couple of different features on the view. A "Check In" button, and a "Update Next Date" button. The result of those buttons will bring up a UIAlertView. I keep getting the "...view is not in the window hierarchy!" error. App doesn't crash, but no AlertView shows... Any insight @chengsam? – szady Mar 06 '17 at 04:22
  • @RyanSady You should open a new question regarding this. – chengsam Mar 06 '17 at 05:23