2017-07-12 14 views
0

URLSessionを使用してWebサーバーからブール値を取得してログインを認証しようとしています。ログインに失敗した場合は警告コントローラを表示します。URLSessionとUI関連のタスク

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) 
} 

私は取得しています奇妙な問題は、警告コントローラで私のログインが時々を解任しないことです。画面をタップすると、次のアラートコントローラが表示されなくなります。非常に迷惑で、どこが間違っているのか分かりません。

これを修正するにはどうすればよいですか?

+0

は、メインスレッドで呼び出さrequestLoginれますか? –

+0

@SandeepBhandari私はそうは思わない。メインスレッドでこれをどのように呼び出すのですか?以前私はメインスレッドについてもエラーがあった。エラーは次のとおりです:NSInternalInconsistencyException _cachedSystemAnimationFenceにアクセスするにはメインスレッドが必要 – iamhx

+0

'showOverlayOnTask'メソッドで作成されたアラートに対してアラートアクションが表示されません。おそらく、 'promptMessage'メソッドで行ったようなokアクションを追加すると –

答えて

2

おそらく問題は、メインスレッドで実行せずにコントローラを終了しようとしていることです。通常、UIの変更/更新はメインスレッドで実行する必要があります。

はこれを試してみて、動作するかどうか確認してください。

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