title: Swift: "Attempt to present UIAlertController whose view is not in the window hierarchy!"
body: <p>I'm trying to display a UIAlertController when a button is clicked (button click runs certain code, and depending on said outcome - the Alert shows up).  The initial ViewController is the default one, and I've created a second one (ConsoleViewController).  The user logs in, and upon successful log in, segues to the next view (ConsoleViewController), which displays data (which is in the viewDidLoad() section of the ConsoleViewController).  Once the user clicks "Check In", the app captures the GPS location of the device, the current date/time, and opens the camera to take a (selfie) picture.  Upon selection of "Use Photo" in the camera (havent coded that feature yet), it sends all 3 parameters to an API handler.  </p>
  
  <p>The second button opens a date picker and the user selects a date and time.  Upon tapping the "Submit" button, a label.text is updated with the selected date (from the date picker), and an Alert should pop up stating the date was successfully saved based on the returnString from the API handler.</p>
  
  <p>The issue I'm having, is that I want an Alert popup to display saying either "Success" or "Failed" depending on if the data was successfully sent or not (based on the returnString of the API handler).  I keep getting the error <code>Warning: Attempt to present &lt;UIAlertController: 0x7fd03961b0a0&gt; on &lt;appName.ViewController: 0x7fd039538640&gt; whose view is not in the window hierarchy!</code>.  I have tried adding the alert view to the main thread, I've tried changing the way the segue is presented (push, modal, etc), and just about everything else I could find here on StackOverFlow (as well as searching Google), and no solution seems to work for me.  I created alerts based on incorrect login credentials (on the ViewController), and that pop up works correctly.  </p>
  
  <p>Below is my code...  Don't mind my random <code>print</code> lines...it helps me keep track of where I am lol.</p>
  
  <p><strong>Note: I have added the corresponding info.plist items to show the correct pop ups from iOS.  These as well, tell me they aren't in the view hierarchy</strong></p>
  
  <pre><code>    func consoleAlertPopup(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))
  }
  </code></pre>
  
  <p>ConsoleViewController:</p>
  
  <pre><code>import UIKit
  import CoreLocation
  import MobileCoreServices
  
  class ConsoleViewController: UIViewController, CLLocationManagerDelegate {
  
  var alertView: UIAlertController?
  
  // IB Outlets \\
  @IBOutlet var DisplayUserName: UILabel!
  @IBOutlet var LastCheckInLabel: UILabel!
  @IBOutlet var NextCourtDateLabel: UILabel!
  @IBOutlet weak var CourtDateButton: UIButton!
  
  @IBOutlet weak var courtDatePicker: UIDatePicker!
  
  //Global Variables &amp; UI Elements
  var checkInImg: UIImage!
  var userNameString: String!
  var newDisplayDate: String?
  var updatedCourtLabel: String?
  let formatter = DateFormatter()
  let displayFormatter = DateFormatter()
  var locationManager: CLLocationManager!
  
  @IBAction func clickCheckIn(_ sender: UIButton) {
  
      sendPicture()
      //Camera Pop Up
  
  }
  
  @IBAction func clickCourtDate() {
  
      courtPickerAction(Any.self)
  
  }
  
  @IBAction func courtPickerAction(_ sender: Any) {
  
  
     DatePickerDialog().show("Select Next Court Date", doneButtonTitle: "Submit", cancelButtonTitle: "Cancel", datePickerMode: .dateAndTime) {
          (courtDateTime) -&gt; Void in
  
      if courtDateTime == nil {
          //Do nothing
      } else {
          self.formatter.dateFormat = "yyyy-MM-dd HH:mm"
          self.newDisplayDate = self.formatter.string(from: (courtDateTime)!)
  
  
      //print("Date after format: \(courtDateTime)")
      print("Date and time: \(self.newDisplayDate) after sendDefendantData func")
  
  
      // Submit Button - Date Picker \\
      if (DatePickerDialog().doneButton != nil) {
  
          self.sendDefendantData()
  
  
          print("Send Defendant Data from Submit")
          print("After sendDefData: \(self.newDisplayDate)")
  
          self.displayFormatter.dateStyle = DateFormatter.Style.full
          self.displayFormatter.timeStyle = DateFormatter.Style.short
          self.NextCourtDateLabel.text = self.displayFormatter.string(from: courtDateTime!)
  
              }
  
          }
      }
  }
  
  
  override func viewDidLoad() {
      super.viewDidLoad()
  
  
      print("Console View Did Load")
      self.hideKeyboardWhenTappedAround()
  
      DisplayUserName.text! = userNameString
      // For location allowance from user
      // I've placed this code here (instead of in a function) so the alert
      // pop up will show and allows accessing location. "not in hierarchy"
      // elsewise.
      self.locationManager = CLLocationManager()
      self.locationManager.delegate = self
      self.locationManager.requestWhenInUseAuthorization()
  
      // Format Display Date &amp; Times
      self.displayFormatter.dateStyle = DateFormatter.Style.full
      self.displayFormatter.timeStyle = DateFormatter.Style.long
  
  
      // Retrieve Defendant Data From API Handler
      getDefendantData()
  
  
  
  
  
      // Do any additional setup after loading the view.
  }
  
  override func didReceiveMemoryWarning() {
      super.didReceiveMemoryWarning()
      // Dispose of any resources that can be recreated.
  }
  
  
  
  
  func presentAlert(_ message: String) {
  
      self.alertView = UIAlertController(title: "Title", message: "Message", preferredStyle: .alert)
      alertView?.addAction(UIAlertAction(title: "OK", style: .cancel) { _ in })
  
      ViewController().present(alertView!, animated: true, completion: nil)
  
  }
  
  
  func consoleAlertPopup(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))
  }
  
  func getDefendantData() {...}
  func sendDefendantData() {...}
  func sendPicture() {....}
  </code></pre>
  
  <p>ViewController:</p>
  
  <pre><code>    import UIKit
  
  
  // Hide Keyboard \\
  extension UIViewController {
      func hideKeyboardWhenTappedAround() {
          let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard))
          view.addGestureRecognizer(tap)
      }
  
      func dismissKeyboard() {
          view.endEditing(true)
      }
  }
  
  
  
  class ViewController: UIViewController {
  
      // Send User Login to Console Screen \\
      override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
  
          if (segue.identifier == "toConsoleScreen") {
  
              let secondViewController = segue.destination as! ConsoleViewController
  
              secondViewController.userNameString = UserNameField.text!
  
              print("PrepareSegue")
          }
  
      }
  
      @IBAction func UserNameEditBegan() {
          UserNameField.text = nil
      }
      @IBAction func PasswordEditBegan() {
          PasswordField.text = nil
      }
  
      @IBOutlet weak var UserNameField: UITextField!
      @IBOutlet weak var PasswordField: UITextField!
  
      func successfulLogin(Username: String) {
  
  
          print("Inside Function")
  
          print(Username)
          print("Inside Successful Login")
  
          // Show next view - Add to Main Queue\\
          OperationQueue.main.addOperation{
  
              //print("Before dismissal")
              // self.dismiss(animated: true, completion: nil)
              //print("After dismissal")
              self.performSegue(withIdentifier: "toConsoleScreen", sender: self)
              print("After segue")
  
          }
      }
  
  
  
      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!) { username in
              self.successfulLogin(Username: username)
      }
  
  
  
  }
  
  
  
      }
  </code></pre>