应用程序恢复后,当注销后,swift解析应用程序崩溃

时间:2015-09-17 21:01:34

标签: ios swift parse-platform crash

我的代码有一个奇怪的错误我无法解决。

我使用swift和parse构建了一个应用程序。您登录,并被带到表视图的主页面。现在,如果您已登录,并离开并返回应用程序,一切都很好,花花公子。

但是,当我退出时,用户将被带回登录屏幕。现在,如果用户离开应用程序,但又返回,则应用程序崩溃时会在展开可选值时意外发现nil错误。

对我来说没有任何意义。当应用程序从头开始新鲜时,用户设置为nil,然后用户登录并且一切都很酷。当您注销时,用户将被设置回nil并进入登录屏幕。如果你恢复应用程序,请崩溃。

这是我注销用户的问题吗?

相关代码张贴在下面..

在登录页面上:

@IBAction func loginButton(sender: AnyObject) {
    //checks if there is a matching username with a matching password. if so, lets the user log in.



    PFUser.logInWithUsernameInBackground(username.text, password: userPassword.text) {
        (user: PFUser?, error: NSError?) -> Void in
        if user != nil {
            // Do stuff after successful login.
            //go to main table view
            //get current user
            //display current users locations
            println("login success")


            //shows home screen after successful login.
            self.performSegueWithIdentifier("showHomeFromLogin", sender: self)
        } else {
            // The login failed. Check error to see why.
            //display error?
            self.displayAlert("Login Failed", alertMessage: "Double check to make sure the username and password are correct.")
            println("login failed")
        }
    }

}


var activeField: UITextField?





override func viewDidLoad() {
    super.viewDidLoad()


    username.delegate = self
    userPassword.delegate = self

    registerForKeyboardNotifications()




    // Do any additional setup after loading the view.
    //setup so when we tap outside the edit, we close keyboard.
    var tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "DismissKeyboard")
    view.addGestureRecognizer(tap)
}


override func viewDidAppear(animated: Bool) {
    if PFUser.currentUser() != nil {
        self.performSegueWithIdentifier("showHomeFromLogin", sender: self)
    }

}

在用户注销的主页上:

@IBAction func logoutButton(sender: AnyObject) {

    PFUser.logOut()
    var currentUser = PFUser.currentUser() // this will now be nil
    self.performSegueWithIdentifier("logoutSegue", sender: self)
}

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "launchSync", name: UIApplicationDidBecomeActiveNotification, object: nil)

    //setting table view datasource and delegate.
    self.tableView.dataSource = self
    self.tableView.delegate = self



    var currentUser = PFUser.currentUser()
    println(currentUser)

}

在这里突破我想在query.whereKey("User", equalTo:PFUser.currentUser()!)行:

func launchSync() {
    var query = PFQuery(className:"ParseLighthouse")
    query.whereKey("User", equalTo:PFUser.currentUser()!)
    query.findObjectsInBackgroundWithBlock {
        (objects: [AnyObject]?, error: NSError?) -> Void in

        if error == nil {
            // The find succeeded.
            println("Successfully retrieved \(objects!.count) lighthouses.")
            // Do something with the found objects
            if let light = objects as? [PFObject] {
                for object in light {
                    println(object.objectId)
                }
            }
            println(objects?.count)
            self.syncToLighthouse(objects!)
        } else {
            // Log details of the failure
            println("Error: \(error!) \(error!.userInfo!)")
        }
    }
}

此视图中的launchsync函数在我的主屏幕上显示方法。是否有可能在执行注销segue时,主视图控制器仍然在后台运行,所以当我恢复时,该代码无法找到用户现在将其设置回nil?

2 个答案:

答案 0 :(得分:1)

如果条件值有可能为零,则需要在使用之前检查条件。如果当前没有登录用户,PFUser.currentUser()将返回nil。当您强制用!打开此值时,您会收到异常。

您可以更改代码以有条件地解包值 -

func launchSync() {
    if let currentUser=PFUser.currentUser() {
        var query = PFQuery(className:"ParseLighthouse")
        query.whereKey("User", equalTo:currentUser)
        query.findObjectsInBackgroundWithBlock {
            (objects: [AnyObject]?, error: NSError?) -> Void in

            if error == nil {
                // The find succeeded.
                println("Successfully retrieved \(objects!.count) lighthouses.")
                // Do something with the found objects
                if let light = objects as? [PFObject] {
                    for object in light {
                        println(object.objectId)
                    }
                }
                println(objects?.count)
                self.syncToLighthouse(objects!)
            } else {
                // Log details of the failure
                println("Error: \(error!) \(error!.userInfo!)")
            }
        }
    } 
}

答案 1 :(得分:1)

在以下一行

NSNotificationCenter.defaultCenter().addObserver(self, selector: "launchSync", name: UIApplicationDidBecomeActiveNotification, object: nil)

你说当应用程序变为活动状态时调用launchSync函数。

正如Paulw11所提到的,你在PFUser.currentUser()内强制展开(使用!),当用户退出时会返回nil。

您可以通过确保当前用户不是

来解决此问题
func launchSync() {
    if (PFUser.currentUser() != nil) {
        var query = PFQuery(className:"ParseLighthouse")
        query.whereKey("User", equalTo:PFUser.currentUser()!)
        query.findObjectsInBackgroundWithBlock {
            (objects: [AnyObject]?, error: NSError?) -> Void in

            if error == nil {
                // The find succeeded.
                println("Successfully retrieved \(objects!.count) lighthouses.")
                // Do something with the found objects
                if let light = objects as? [PFObject] {
                    for object in light {
                        println(object.objectId)
                    }
                }
                println(objects?.count)
                self.syncToLighthouse(objects!)
            } else {
                // Log details of the failure
                println("Error: \(error!) \(error!.userInfo!)")
            }
        }
    }
}