Swift 未能登录导致未编码序列?

Swift 未能登录导致未编码序列?,swift,xcode,parse-server,Swift,Xcode,Parse Server,我已经设置了一个应用程序,用户可以在其中登录和注销(这是通过heroku托管的带有解析框架的解析服务器处理的) 要登录,用户输入凭证,如果服务器验证凭证,segue会将凭证移动到另一个viewcontroller。注销会让用户退出应用程序,并将其切换回登录屏幕。这些很好用 如果初始登录凭据不正确,将显示一个警报,提示用户重试,并且用户未登录(显然),并留在登录屏幕上 但是,如果用户登录、注销,然后输入错误的凭据(按此顺序,不关闭模拟器),则会出现问题。不正确的凭证会引发提示警报;点击“确定”将关

我已经设置了一个应用程序,用户可以在其中登录和注销(这是通过heroku托管的带有解析框架的解析服务器处理的)

要登录,用户输入凭证,如果服务器验证凭证,segue会将凭证移动到另一个viewcontroller。注销会让用户退出应用程序,并将其切换回登录屏幕。这些很好用

如果初始登录凭据不正确,将显示一个警报,提示用户重试,并且用户未登录(显然),并留在登录屏幕上

但是,如果用户登录、注销,然后输入错误的凭据(按此顺序,不关闭模拟器),则会出现问题。不正确的凭证会引发提示警报;点击“确定”将关闭警报,用户未登录,但视图将切换到注销屏幕(其中注销按钮为…,这应仅可供登录用户访问)。不存在将用户从登录直接移动到注销屏幕的segue segue(编码或在故事板上)

由于许多操作需要用户ID,因此无法执行任何操作;由于没有用户登录,因此无法执行任何操作。我不知道为什么不正确的登录会以这种方式移动VC,因为不存在可以这样做的segue。有一个会反向移动(注销时),但没有一个会朝这个方向移动

有人有什么想法吗?下面是相关的登录代码

@IBAction func signInTapped(_ sender: UIButton) {
        UIApplication.shared.beginIgnoringInteractionEvents()

        PFUser.logInWithUsername(inBackground: userNameTextField.text!, password: passwordTextField.text!, block: { (user, error) in
            if user != nil{

                self.performSegue(withIdentifier: "signInSegue", sender: self)//if the sign in works    
            } else{

                if let errorString = (error! as NSError).userInfo["error"] as? String{

                    let errorMessage = errorString

                    self.displayAlert("Failed login", message: errorMessage)//this is the code run when the login fails, yet it somehow can sometimes segue to the other viewcontroller
                }   
            }
        })
}
下面是正在发生的事情的逐步示意图。

  • 用户从登录页面开始,输入其凭据
  • 这会将用户(现在已登录)分隔到
    tabbarViewController
  • 然后,他们导航到另一个选项卡,并有一个注销按钮
  • 按下“注销”按钮将显示警报,点击“是”将用户(现在已注销)切换到原始屏幕
  • 用户现在处于登录屏幕。输入错误的信息会引发警报
  • 此时会出现警报。点击yes(是)关闭警报,用户应留在登录屏幕上。然而,有一个立即的序列到注销屏幕再次。。。这既不是编码的,也不是在情节提要中手动设置的
  • 我认为可能相关的随机事件: 打开应用程序时,会在第一个VC(登录屏幕)的
    viewdide
    上调用一个初始序列。它检查是否有用户登录,通过

    if PFUser.current().username? != nil {
          //perform segue
    }
    
    这个序列将他们带到选项卡栏上的地图部分(而不是问题发生时的注销页面)

    编辑:当“切换”到注销屏幕时,登录屏幕会下降(就像字面意思一样,在屏幕上向下下降,直到看不到为止,注销屏幕是可查看的,这不是应用程序功能中任何分段的方式)。此外,在发生此转换时,仅调用
    viewdide
    代码,而不调用
    viewdideload
    代码

    编辑2:我认为这个问题与视图层次结构有关。以下是登录功能的代码:

    PFUser.logInWithUsername(inBackground: userNameTextField.text!, password: passwordTextField.text!, block: { (user, error) in
    
                if user?.username != nil{ 
                    self.performSegue(withIdentifier: "signInSegue", sender: self) 
                } else{ //if everything in this code block is commented, the issue does not occur
                    if let errorString = (error! as NSError).userInfo["error"] as? String{
                        let errorMessage = errorString
                        self.displayAlert("Failed login", message: errorMessage)
                    }  
                }
            })
    

    如果我注释掉If语句的
    else
    部分中的所有内容,则不会出现问题。我认为正在发生的是,警报被显示,点击“ok”关闭警报,并将应用程序发送回最顶端(可能我称之为viewController的说法有误)的viewController,它不知何故就是注销VC。我认为解决这个问题的一个好方法是在
    其他
    代码中添加一个
    self.present(homescreenVC)
    或类似的东西,但我不知道如何做到这一点。

    演示控制器就是您认为的控制器吗?我假设你没有释放序列?在你的文章中,你提到了用户注销然后输入凭据。这意味着从注销状态到登录功能的某种转换。他们是如何从注销屏幕进入登录屏幕的?看起来您正在通过
    iAction
    (点击)从注销状态进入登录部分。。。?我不知道
    PFUser.loginWithUsername()
    做了什么,但自从登录失败后,似乎没有创建明显的序列。我不知道你的
    displayAlert()
    方法完成后会做什么。你也能展示一下吗?@HotAppleCyber 1)我不知道什么是放松阶段,所以我认为我没有实现任何2)有一个注销函数,名为。一旦用户从系统注销,一个
    performsgue
    会将他们从注销屏幕移动到登录屏幕3)PFUser.loginWithUsername()将用户登录到系统中。。。它用数据库中的用户凭据验证用户凭据。。。如果正确,则表示用户已登录。当登录失败时,没有任何序列。警报显示,用户点击ok,并且仍然在登录屏幕上(当它正常工作时),我以前不得不在我自己的代码中解决segues的奇怪问题。这可能是一个真正的挑战和麻烦。阅读我发布的一些文章,了解放松,试着熟悉segues的基本机制,这将帮助你诊断和解决它。可能需要一些时间。事情就是这样。
    @IBAction func signInTapped(_ sender: UIButton) {
        UIApplication.shared.beginIgnoringInteractionEvents()
    
        PFUser.logInWithUsername(inBackground: userNameTextField.text!, password: passwordTextField.text!, block: { (user, error) in
            if error != nil {
                 if let errorString = (error! as NSError).userInfo["error"] as? String{
    
                    let errorMessage = errorString
    
                    self.displayAlert("Failed login", message: errorMessage)
                   }
            } 
            else {
                self.performSegue(withIdentifier: "signInSegue", sender: self)
    
                }   
            })
        }