不明白为什么我会收到 Parse 206 错误 (UserCannotBeAlteredWithoutSessionError)
Don't understand why I am getting Parse 206 error (UserCannotBeAlteredWithoutSessionError)
PFCloud.callFunctionInBackground("updatePositions", withParameters: ["username" : username, "location" : locationTitle, "instructor" : instructorSwitch.on, "guard" : guardSwitch.on, "sup" : supSwitch.on]) {
(positions: AnyObject!, error: NSError!) -> Void in
if error == nil {
self.currentUser.setValue(self.instructorSwitch.on, forKey: (self.shortTitle + "Instructor"))
self.currentUser.setValue(self.guardSwitch.on, forKey: (self.shortTitle + "Guard"))
self.currentUser.setValue(self.supSwitch.on, forKey: (self.shortTitle + "Sup"))
self.currentUser.save(nil)
self.navigationController?.popToRootViewControllerAnimated(true)
}
else {
let errorAlert = UIAlertController (title: "Error", message: "There was an error while processing your request. This may be because the app could not connect to the internet. Please try again.", preferredStyle: UIAlertControllerStyle.Alert)
let actionCancel = UIAlertAction (title: "Dismiss", style: .Cancel, handler: nil)
errorAlert.addAction(actionCancel)
self.presentViewController(errorAlert, animated: true, completion: nil)
}
当我 运行 上面的代码时,我的目标是更新我的数据浏览器中的解析对象,同时在 currentUser
.
中编辑相同的对象
就目前而言,如果没有人登录(基于 Core Data 中的布尔值),则会显示登录 VC。当用户登录时,他们将被带到应用程序主页(并且布尔值已更改)。如果他们要关闭应用程序并重新启动,他们将被带到主页而不是登录 VC。我有一个 "dummy" VC 更新了核心数据实体(我知道这听起来多余,但它的目的与我的问题无关)。
登录VC
@IBOutlet var fullName: UITextField!
@IBOutlet var password: UITextField!
@IBOutlet var helpButton: UIButton!
@IBOutlet var loginButton: UIButton!
var nameID: String!
var passwordStatus: Bool?
var username: String?
var userID: String?
var objectID: String!
var currentUser = PFUser.currentUser()
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.hidesBackButton = true
checkInternetConnection()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
self.view.endEditing(true)
}
@IBAction func LoginTapped(sender: AnyObject) {
if (fullName.text.isEmpty || password.text.isEmpty) {
let alert = UIAlertView()
alert.title = "Error"
alert.message = "You have not completed the required fields!"
alert.addButtonWithTitle("Dismiss")
alert.show()
}
else {
PFUser.logInWithUsernameInBackground(fullName.text, password: password.text) {
(user: PFUser!, error: NSError!) -> Void in
if (user != nil) {
self.currentUser = user
self.currentUser.save()
//println(self.currentUser.objectForKey("username") as String!)
if (self.currentUser.objectForKey("passwordChanged") as Bool! == nil || self.currentUser.objectForKey("passwordChanged") as Bool! == false) {
self.performSegueWithIdentifier("password", sender: self)
}
else {
self.performSegueWithIdentifier("skipPassword", sender: self)
}
}
else {
let errorAlert = UIAlertController (title: "Error", message: "Profile not found. Please check your username and password.", preferredStyle: UIAlertControllerStyle.Alert)
let actionCancel = UIAlertAction (title: "Dismiss", style: .Cancel, handler: nil)
errorAlert.addAction(actionCancel)
self.presentViewController(errorAlert, animated: true, completion: nil)
}
}
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "password") {
var svc = segue.destinationViewController as AccountSetup
svc.username = fullName.text
}
else if (segue.identifier == "skipPassword") {
var svc = segue.destinationViewController as Agree
svc.password = password.text
}
}
用户唯一有机会退出的地方是在应用程序的设置控制器中:
设置VC
var choice: String!
var currentEmail: String!
var sendEmail: String!
var email: UITextField!
var listArray = NSArray (objects: "-", "-", "-", "1", "2", "3", "4", "5", "6")
var currentUser = PFUser.currentUser()
var res : NSManagedObject!
var context : NSManagedObjectContext!
override func viewDidLoad() {
super.viewDidLoad()
currentEmail = currentUser.objectForKey("email") as String!
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return 4
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows in the section.
switch(section) {
case 0: return 2
case 1: return 9
case 2: return 4
case 3: return 1
default: fatalError("Unknown number of sections")
}
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
choice = listArray.objectAtIndex(indexPath.row) as NSString
if (indexPath.row >= 3) {
performSegueWithIdentifier("positions", sender: self)
}
else if (indexPath.row == 1) {
var passwordAlert = UIAlertController (title: "Change Password", message: "For security reasons, you can not change your password through the app. We will send an email to " + currentEmail + ". If you rather us send it to another email, enter it below. Otherwise, click 'Send'.", preferredStyle: UIAlertControllerStyle.Alert)
let standardCancel = UIAlertAction (title: "Dismiss", style: .Cancel, handler: nil)
let actionSubmit = UIAlertAction (title: "Send", style: .Default) { (action) in
if (self.email.text.isEmpty) {
self.sendEmail = self.currentEmail
}
else {
self.sendEmail = self.email.text
}
PFUser.requestPasswordResetForEmailInBackground(self.sendEmail){
(success: Bool!, error: NSError!) -> Void in
if (success == true) {
let emailAlert = UIAlertController (title: "Password", message: "An email containing information on how to change your password has been sent to " + self.sendEmail + ".", preferredStyle: UIAlertControllerStyle.Alert)
emailAlert.addAction(standardCancel)
self.presentViewController(emailAlert, animated: true, completion: nil)
}
else {
let errorAlert = UIAlertController (title: "Error", message: "There was an error while processing your request. This may be because the email is invalid or the app could not connect to the internet. Please try again.", preferredStyle: UIAlertControllerStyle.Alert)
errorAlert.addAction(standardCancel)
self.presentViewController(errorAlert, animated: true, completion: nil)
}
}
}
let actionCancel = UIAlertAction (title: "Cancel", style: .Cancel, handler: nil)
passwordAlert.addTextFieldWithConfigurationHandler {
(textField) in textField.placeholder = "Email"
self.email = textField
}
passwordAlert.addAction(actionSubmit)
passwordAlert.addAction(actionCancel)
self.presentViewController(passwordAlert, animated: true, completion: nil)
}
}
@IBAction func logoutPressed (sender: AnyObject) {
PFUser.logOut()
//code to change Core Data boolean value to start on Login is here but there is no need to put it (unrelated)
tabBarController?.tabBar.hidden = true
performSegueWithIdentifier("goToLogin", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "positions") {
var svc = segue.destinationViewController as UpdatePositions;
svc.locationTitle = choice
println (choice)
}
}
就像我之前提到的,一切正常,直到应用程序关闭并丢失身份验证。
最后说1.6.0 Parse SDK 有错误。适用于 1.6.5。
PFCloud.callFunctionInBackground("updatePositions", withParameters: ["username" : username, "location" : locationTitle, "instructor" : instructorSwitch.on, "guard" : guardSwitch.on, "sup" : supSwitch.on]) {
(positions: AnyObject!, error: NSError!) -> Void in
if error == nil {
self.currentUser.setValue(self.instructorSwitch.on, forKey: (self.shortTitle + "Instructor"))
self.currentUser.setValue(self.guardSwitch.on, forKey: (self.shortTitle + "Guard"))
self.currentUser.setValue(self.supSwitch.on, forKey: (self.shortTitle + "Sup"))
self.currentUser.save(nil)
self.navigationController?.popToRootViewControllerAnimated(true)
}
else {
let errorAlert = UIAlertController (title: "Error", message: "There was an error while processing your request. This may be because the app could not connect to the internet. Please try again.", preferredStyle: UIAlertControllerStyle.Alert)
let actionCancel = UIAlertAction (title: "Dismiss", style: .Cancel, handler: nil)
errorAlert.addAction(actionCancel)
self.presentViewController(errorAlert, animated: true, completion: nil)
}
当我 运行 上面的代码时,我的目标是更新我的数据浏览器中的解析对象,同时在 currentUser
.
就目前而言,如果没有人登录(基于 Core Data 中的布尔值),则会显示登录 VC。当用户登录时,他们将被带到应用程序主页(并且布尔值已更改)。如果他们要关闭应用程序并重新启动,他们将被带到主页而不是登录 VC。我有一个 "dummy" VC 更新了核心数据实体(我知道这听起来多余,但它的目的与我的问题无关)。
登录VC
@IBOutlet var fullName: UITextField!
@IBOutlet var password: UITextField!
@IBOutlet var helpButton: UIButton!
@IBOutlet var loginButton: UIButton!
var nameID: String!
var passwordStatus: Bool?
var username: String?
var userID: String?
var objectID: String!
var currentUser = PFUser.currentUser()
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.hidesBackButton = true
checkInternetConnection()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
self.view.endEditing(true)
}
@IBAction func LoginTapped(sender: AnyObject) {
if (fullName.text.isEmpty || password.text.isEmpty) {
let alert = UIAlertView()
alert.title = "Error"
alert.message = "You have not completed the required fields!"
alert.addButtonWithTitle("Dismiss")
alert.show()
}
else {
PFUser.logInWithUsernameInBackground(fullName.text, password: password.text) {
(user: PFUser!, error: NSError!) -> Void in
if (user != nil) {
self.currentUser = user
self.currentUser.save()
//println(self.currentUser.objectForKey("username") as String!)
if (self.currentUser.objectForKey("passwordChanged") as Bool! == nil || self.currentUser.objectForKey("passwordChanged") as Bool! == false) {
self.performSegueWithIdentifier("password", sender: self)
}
else {
self.performSegueWithIdentifier("skipPassword", sender: self)
}
}
else {
let errorAlert = UIAlertController (title: "Error", message: "Profile not found. Please check your username and password.", preferredStyle: UIAlertControllerStyle.Alert)
let actionCancel = UIAlertAction (title: "Dismiss", style: .Cancel, handler: nil)
errorAlert.addAction(actionCancel)
self.presentViewController(errorAlert, animated: true, completion: nil)
}
}
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "password") {
var svc = segue.destinationViewController as AccountSetup
svc.username = fullName.text
}
else if (segue.identifier == "skipPassword") {
var svc = segue.destinationViewController as Agree
svc.password = password.text
}
}
用户唯一有机会退出的地方是在应用程序的设置控制器中:
设置VC
var choice: String!
var currentEmail: String!
var sendEmail: String!
var email: UITextField!
var listArray = NSArray (objects: "-", "-", "-", "1", "2", "3", "4", "5", "6")
var currentUser = PFUser.currentUser()
var res : NSManagedObject!
var context : NSManagedObjectContext!
override func viewDidLoad() {
super.viewDidLoad()
currentEmail = currentUser.objectForKey("email") as String!
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return 4
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows in the section.
switch(section) {
case 0: return 2
case 1: return 9
case 2: return 4
case 3: return 1
default: fatalError("Unknown number of sections")
}
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
choice = listArray.objectAtIndex(indexPath.row) as NSString
if (indexPath.row >= 3) {
performSegueWithIdentifier("positions", sender: self)
}
else if (indexPath.row == 1) {
var passwordAlert = UIAlertController (title: "Change Password", message: "For security reasons, you can not change your password through the app. We will send an email to " + currentEmail + ". If you rather us send it to another email, enter it below. Otherwise, click 'Send'.", preferredStyle: UIAlertControllerStyle.Alert)
let standardCancel = UIAlertAction (title: "Dismiss", style: .Cancel, handler: nil)
let actionSubmit = UIAlertAction (title: "Send", style: .Default) { (action) in
if (self.email.text.isEmpty) {
self.sendEmail = self.currentEmail
}
else {
self.sendEmail = self.email.text
}
PFUser.requestPasswordResetForEmailInBackground(self.sendEmail){
(success: Bool!, error: NSError!) -> Void in
if (success == true) {
let emailAlert = UIAlertController (title: "Password", message: "An email containing information on how to change your password has been sent to " + self.sendEmail + ".", preferredStyle: UIAlertControllerStyle.Alert)
emailAlert.addAction(standardCancel)
self.presentViewController(emailAlert, animated: true, completion: nil)
}
else {
let errorAlert = UIAlertController (title: "Error", message: "There was an error while processing your request. This may be because the email is invalid or the app could not connect to the internet. Please try again.", preferredStyle: UIAlertControllerStyle.Alert)
errorAlert.addAction(standardCancel)
self.presentViewController(errorAlert, animated: true, completion: nil)
}
}
}
let actionCancel = UIAlertAction (title: "Cancel", style: .Cancel, handler: nil)
passwordAlert.addTextFieldWithConfigurationHandler {
(textField) in textField.placeholder = "Email"
self.email = textField
}
passwordAlert.addAction(actionSubmit)
passwordAlert.addAction(actionCancel)
self.presentViewController(passwordAlert, animated: true, completion: nil)
}
}
@IBAction func logoutPressed (sender: AnyObject) {
PFUser.logOut()
//code to change Core Data boolean value to start on Login is here but there is no need to put it (unrelated)
tabBarController?.tabBar.hidden = true
performSegueWithIdentifier("goToLogin", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "positions") {
var svc = segue.destinationViewController as UpdatePositions;
svc.locationTitle = choice
println (choice)
}
}
就像我之前提到的,一切正常,直到应用程序关闭并丢失身份验证。
最后说1.6.0 Parse SDK 有错误。适用于 1.6.5。