2017-07-12 1 views
0

Ich versuche die Anmeldung zu authentifizieren, indem ich einen Boolean von meinem Webserver mit URLSession abruft, und einen Alert-Controller anzeigen, wenn die Anmeldung fehlschlägt.URLSession- und UI-bezogene Aufgaben

func requestLogin() { 
    let url = URL(string: "http://mywebserver/login.php") 
    var request = URLRequest(url: url!) 
    request.httpMethod = "POST" 
    let postString = "username=\(txtUsername.text!)&password=\(txtPassword.text!)" 
    request.httpBody = postString.data(using: .utf8) 
    let task = URLSession.shared.dataTask(with: request, completionHandler: { data, response, error in 
     guard data != nil else { 
      self.promptMessage(message: "No data found") 
      return 
     } 
     do { 
      if let jsonData = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary { 
       let success = jsonData.value(forKey: "success") as! Bool 
       if (success) { 
        self.dismiss(animated: false, completion: { action in 
         //Move to next VC 
        }) 
        return 
       } else { 
        self.dismiss(animated: false, completion: { action in 
         self.promptMessage(message: "The username or password that you have entered is incorrect. Please try again.")} 
        ) 
        return 
       } 
      } else { 
       self.dismiss(animated: false, completion: { action in 
        self.promptMessage(message: "Error: Could not parse JSON!") 
       }) 
      } 
     } catch { 
      self.dismiss(animated: false, completion: { action in 
       self.promptMessage(message: "Error: Request failed!") 
      }) 
     } 
    }) 
    showOverlayOnTask(message: "Logging in...") 
    task.resume() 
} 

func promptMessage(message: String) { 
    let alert = UIAlertController(title: "Login Failed", message: message, preferredStyle: .alert) 
    let okAction = UIAlertAction(title: "OK", style: .default, handler: nil) 
    alert.addAction(okAction) 
    self.present(alert, animated: true, completion: nil) 
} 

func showOverlayOnTask(message: String) { 
    let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert) 
    let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50)) 
    loadingIndicator.hidesWhenStopped = true 
    loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray 
    loadingIndicator.startAnimating(); 
    alert.view.addSubview(loadingIndicator) 
    self.present(alert, animated: true, completion: nil) 
} 

Das seltsame Problem, das ich bin immer ist, dass mein Anmelden bei Alarm Controller manchmal nicht entlässt. Es bleibt hängen, bis ich auf den Bildschirm klicke, der dann den nächsten Alarm-Controller abstellt und anzeigt. Es ist sehr nervig und ich weiß nicht, wo ich falsch liege.

Wie behebe ich das?

+0

auf Hauptthread aufgerufen wird requestLogin? –

+0

@SandeepBhandari Ich denke nicht. Wie rufe ich das auf dem Hauptthread auf? Früher hatte ich einen Fehler, der auch über Hauptthread war. Der Fehler war: NSInternalInconsistencyException Zugriff auf _cachedSystemAnimationFence erfordert den Hauptthread – iamhx

+0

Ich sehe keine Alert-Aktion für die Warnung erstellt in 'showOverlayOnTask' Methode. Vielleicht, sobald Sie eine "OK" -Aktion hinzufügen, ähnlich wie bei der "promptMessage" -Methode –

Antwort

2

Vielleicht ist das Problem, dass Sie versuchen, den Controller zu schließen, ohne auf dem Hauptthread auszuführen, normalerweise sollte die UI Änderungen/Updates auf dem Hauptthread ausgeführt werden.

Versuchen Sie dies und überprüfen, ob Werke:

DispatchQueue.main.async { 
    self.dismiss(animated: false, completion: { action in 
      self.promptMessage(message: "Error: Could not parse JSON!") 
    }) 
}