I have a save button to save Score and Playername to GameScore in Parse. When I load the GameScore from Parse I want to set the value that i loaded to the variable "score". This don't work, can anyone please tell me what i am doing wrong?
Thanks
Exapmle: let score = gameScore["score"] as Int
// Load button tapped
#IBAction func loadButtonTapped(sender: UIButton) {
var query = PFQuery(className:"GameScore")
query.getObjectInBackgroundWithId("F1efANYzOE") {
(gameScore: PFObject?, error: NSError?) -> Void in
if error == nil && gameScore != nil {
println(gameScore)
let score = gameScore["score"] as Int
} else {
println(error)
}
}
}
}
Try this following code for retrieving specific data from specific columns. You have to enter your object name, Object ID and column name in the below code and run it. It will work.
let query = PFQuery(className:"Your Object name")
query.getObjectInBackgroundWithId("Your Object ID") {
(gameScore: PFObject?, error: NSError?) -> Void in
if error == nil {
print(gameScore!.objectForKey("your column name") as! String)
} else {
print(error)
}
}
Related
I am trying to update a few columns on parse. Here , only gotpromoCode gets updated before segue . But if I come back from the next view controller, on the same button click function gets called again and other columns promoCode and senderUserId are updated. I have set breakpoints and seen that the code for updating the columns is called before segue for these two columns but first time they are still not getting updated.
var promoCode = ""
//if promocode is nil
if ((self.currentUser["promoCode"]) == nil)
{
let nameString = self.firstname.text!+self.lastname.text!
PFCloud.callFunctionInBackground("createPromoCode", withParameters: ["nameString" : nameString]){ response, error in
if let error = error {
print (error)
}
else {
print("Invite sent")
print("the invitation code is: \(String(response!))")
promoCode = String(response!)
PFUser.currentUser()!.setValue(promoCode, forKey: "promoCode")
}
}
}
//validating promo code
if ( self.promocodeText.text?.isEmpty == false )// && PFUser.currentUser()!["gotpromoCode"] == nil )
{
var query1 = PFQuery(className:"_User")
query1.whereKey("promoCode", equalTo:self.promocodeText.text!)
query1.findObjectsInBackgroundWithBlock {
(objects: [PFObject]?, error: NSError?) -> Void in
if error == nil {
PFUser.currentUser()!.setValue(self.promocodeText.text, forKey: "gotpromoCode")
// The find succeeded.
print("Successfully retrieved \(objects!.count) scores.")
// Do something with the found objects
if let objects = objects {
for object in objects {
print(object.objectId)
// self.senderUserId = object.objectId!
PFUser.currentUser()!.setValue(object.objectId!, forKey: "senderUserId")
print("senderUserId is: \(object.objectId!)")
}
}
} else {
// Log details of the failure
print("Error: \(error!) \(error!.userInfo)")
self.displayAlert("Error!", body: "Promo Code does not exists")
}
}
}
PFUser.currentUser()!.saveInBackgroundWithBlock {
(success: Bool, error: NSError?) -> Void in
if (success) {
self.performSegueWithIdentifier(self.goToAccount, sender: self)
} else {
// There was a problem, check error.description
}
}
I have checked the values in breakpoints and am out of ideas why this is happening.
I solved it by saving the result after setting the values.
PFUser.currentUser()!.saveInBackground()
so I used this like
PFUser.currentUser()!.setValue(object.objectId!, forKey: "senderUserId")
PFUser.currentUser()!.saveInBackground()
similarly for the promoCode , then it worked.
I want to know how I could store the entire custom column (the user Pointer<_User> column from a custom class) and put them all in an array variable so that I can see if a the user exists in that class or not. This is what I have:
Old Code
var objectUserIdArray = [String]()
let objectUserIdQuery : PFQuery = PFQuery(className: "Scores")
objectUserIdQuery.findObjectsInBackgroundWithBlock {
(objects : [PFObject]? , error : NSError?) -> Void in
var objectID = objects! as [PFObject]
for i in 0..<objectID.count {
objectUserIdArray.append(objectID[i].objectId!)
}
for _ in objectID {
print(objectUserIdArray)
}
New Code
func saveScoresOnParse() {
objectUserIdQuery.whereKey("User", equalTo: PFObject(withoutDataWithClassName: "_User", objectId: userID))
objectUserIdQuery.findObjectsInBackgroundWithBlock {
(objects : [PFObject]? , error : NSError?) -> Void in
if error == nil {
//var objectID = objects! as [PFObject]
/*for i in 0..<objectID.count {
self.objectUserIdArray.append( objectID[i].objectId! )
}*/
for _ in objects! {
print(objects)
}
// The score key has been incremented
for (var i = 0 ; i < self.objectUserIdArray.count ; i++) {
if self.userID != objects![i] {
print("New Scores")
print("R: \(self.rightAnswers)")
print("W: \(self.wrongAnswers)")
print("S: \(self.skippedQuestions)")
self.scores["User"] = PFUser.currentUser()
self.scores["Right"] = self.rightAnswers
self.scores["Wrong"] = self.wrongAnswers
self.scores["Skipped"] = self.skippedQuestions
self.scores.saveInBackground()
} else if self.userID == objects![i] {
print("Updated Scores")
self.scores.incrementKey("Right", byAmount: 1)
self.scores.incrementKey("Wrong", byAmount: 1)
self.scores.incrementKey("Skipped", byAmount: 1)
print("R: \(self.rightAnswers)")
print("W: \(self.wrongAnswers)")
print("S: \(self.skippedQuestions)")
self.scores.saveInBackgroundWithBlock {
(success: Bool, error: NSError?) -> Void in
if (success) {
// The score key has been incremented
} else {
// There was a problem, check error.description
}
}
} else {
print("Error")
}
}
} else {
print(error)
}
}
But it only stores the objectId column and not the Pointer<_User> column. I know this because when I print the stuff that is inside, it prints out the objectIds.
This is what happens, instead of just updating the current user's scores, it just makes new ones. I want the if statement to check if the user already exists in that column and if it does updates the scores and if it doesn't, make new ones. (The new code's if statement doesn't work, i have to bring it out for it to save...)
Your updated question make clearer what you are actually wanting to do;
Save or update a user's scores in your Parse Score object. To do this, there is no reason to retrieve any object Ids or loop through any results. More often than not you don't do use Object Ids explicitly when using Parse; you can simply pass the object itself with Parse working out the references for you.
I am not sure how you exactly want to change the scores; in your code above you increment in one case but set the scores explicitly in another, but the code below shows the general approach.
If you are frequently or repeatedly going to update a score record then you could make your code more efficient by holding a reference to the Scores object in a property after you find it the first time and simply update & save it subsequently.
func saveScoresOnParse() {
if let currentUser=PFUser.currentUser() {
let scoreQuery= PFQuery(className: "Scores")
scoreQuery.whereKey("User",equalTo:currentUser)
scoreQuery.getFirstObjectInBackgroundWithBlock {
(object : PFObject? , error : NSError?) -> Void in
if error == nil {
var scoreObject=object ?? PFObject.objectWithClassName("Scores")
if (scoreObject["User"]==nil) {
scoreObject["User"]=currentUser
}
scoreObject["Right"]=self.rightAnswers
scoreObject.saveInBackground()
} else {
print(error)
}
}
} else {
print("No current user!")
}
}
I'm trying to check if username is already taken in parse or not, but seems don't work with my code, can you please what i'm doing wrong on it
Thanks
func usernameIsTaken(userName: String) -> Bool {
let userName = userNameTextField.text
let myUser: PFUser = PFUser.currentUser()!
//bool to see if username is taken
var isTaken : Bool = false
//access PFUsers
let query = PFUser.query()
query!.whereKey("username", equalTo: userName!)
query!.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]? , error : NSError? ) in
if error == nil {
if (objects!.count > 0) {
isTaken = true
print("username is taken")
} else {
print("Username is available. ")
}
} else {
print("error")
}
}
return isTaken
}
For one, you can attempt to sign the user up and Parse will return an error code of 202 if the username has already been taken.
http://parse.com/docs/dotnet/api/html/T_Parse_ParseException_ErrorCode.htm
If this isn't your intended use, to query the User table, use PFUser.query to construct a query instead.
Try this :
query.findObjectsInBackgroundWithBlock({ (object: [PFObject]?,error: NSError?) -> Void in
if error == nil {
}
})
With that being said if your only Interested in the count parse introduced a new method similar to findObjectsInBackground but does exactly what you are looking for, the method is called countObjectsInBackground
You can call this method after you define your query.
like so
query.countObjectsInBackgroundWithBlock { (count: Int32,error: NSError?) -> Void in
if error == nil {
//code here
}
Hope this helps
This is my code that tries to save the table/Class inscricoes
view.showHUD(view)
var inscricaoClass = PFObject(className: INSCRICAO_CLASS_NAME)
inscricaoClass[INSCRICAO_SORTEIO_ID] = self.eventObj.objectId
inscricaoClass.saveInBackgroundWithBlock { (success, error) -> Void in
if error == nil {
self.view.hideHUD()
} else { errorAlert.show(); self.view.hideHUD() }
}
This is my class / table where sorteioId is a pointer to my table/class sorteios
when I try to save an error of warning that can not save as a string pointer.
[Error]: invalid type for key sorteioId, expected Sorteios, but got string (Code: 111, Version: 1.7.5)
How do I send a pointer to table / class using parse?
You first need an instance of PFObject of type Sorteios. Revise your code like so:
view.showHUD(view)
var query = PFQuery(className: "Sorteios")
query.getObjectInBackgroundWithId(self.eventObj.objectId) {
(object: PFObject?, error: NSError?) -> Void in
if error == nil && object != nil {
// after finding Sorteios, you can assign it to inscricaoClass
var inscricaoClass = PFObject(className: INSCRICAO_CLASS_NAME)
inscricaoClass[INSCRICAO_SORTEIO_ID] = object
inscricaoClass.saveInBackgroundWithBlock { (success, error) -> Void in
if error == nil {
self.view.hideHUD()
} else {
errorAlert.show(); self.view.hideHUD() }
}
}
}
I use parse for my app. I want to let user able to type messages that they want to send via textField and save it to that user's messages column in parse with PFRelation via save button in view controller and the messages will be saved as an array and show it in tableView.
The problem is I don't know how to add text in textfield to an array and save it to parse.
Any help is appreciated and let me know if you need any additional information!
UPDATE:
These are screenshots of my parse's class "User"
This is my current user's friend list inside "Friends" column
I've not yet create Messages column because when run relationForKey code in Xcode it will automatically create for me
UPDATE 2:
This is my code:
#IBAction func addMessage(sender: AnyObject) {
var newMessage = addMessageText.text
let message = PFObject(className: "Messages")
var query = PFQuery(className: "Messages")
message["messageTextColumn"] = newMessage
message.saveInBackgroundWithBlock {
(success: Bool, error: NSError?) -> Void in
if (success) {
println("added to Message Class")
query.whereKey("messageTextColumn", equalTo: newMessage)
query.getFirstObjectInBackgroundWithBlock{(object:PFObject!, error: NSError!) -> Void in
if error == nil {
let relation = PFUser.currentUser().relationForKey("Messages")
var addMessageWithObject = object
if addMessageWithObject != nil {
relation.addObject(addMessageWithObject)
println("Added with getFirstObject")
}
else{
println("Error Added with getFirstObject")
}
}
}
} else {
println("added to Message class Error")
}
}
}
I save new message to the array first and then I save it with saveInBackgroundWithBlock.. and inside I query that message to add it to relation.
The messages that I've added appear on Messages class table but not in that user's relation but it shows log
"added to Message Class" and "Added with getFirstObject"
Which means that my code execute exactly like it should be. Probably about the method?
UPDATE 3 this is the object println
<Messages: 0x7fd4484f75f0, objectId: LFXoSaHfQl, localId: (null)> {
ACL = "<PFACL: 0x7fd4484d2e70>";
messageTextColumn = 9;
}
UPDATE 4
this is my code
#IBAction func addMessage(sender: AnyObject) {
var newMessage = addMessageText.text
let message = PFObject(className: "Messages")
var user = PFUser.currentUser()
var query = PFQuery(className: "Messages")
message["messageTextColumn"] = newMessage
message.saveInBackgroundWithBlock {
(success: Bool, error: NSError?) -> Void in
if (success) {
println("added to Message Class")
query.getFirstObjectInBackgroundWithBlock{(object:PFObject!, error: NSError!) -> Void in
if error == nil {
var addMessageWithObject = object
if addMessageWithObject != nil {
user.saveInBackground()
println("Added with getFirstObject")
}
else{
println("Error Added with getFirstObject")
}
}
}
}
}
}
user column is (undefined) as in screenshot here
and the error log can't add non pointer to relation is back
how do I fix this? Thanks!
Here's what you do:
Manually create your Message table on Parse
Add a messages column to your user table of type Relation with Target Class as your Message table.
In your code, in your buttons trigger:
// Get the message text from your textField
let messageText = textField.text
// Create your new Message object
let newMessage = PFObject(className: "Message")
// ... Add your data to your new message object
newMessage["messageTextColumn"] = messageText
newMessage.saveInBackgroundWithBlock {
(success: Bool, error: NSError?) -> Void in
if (success) {
// Add the new message to the user's relation
let relation = yourUser.relationForKey("messagesColumnName")
relation.addObject(newMessage)
// Save the user object
yourUser.saveInBackground()
} else {
// There was a problem, check error.description
}
}
Here's a link to Parse's Relation reference.
UPDATE:
Missing code to save your user object.
query.getFirstObjectInBackgroundWithBlock{(object:PFObject!, error: NSError!) -> Void in
if error == nil {
let relation = PFUser.currentUser().relationForKey("Messages")
var addMessageWithObject = object
if addMessageWithObject != nil {
relation.addObject(addMessageWithObject)
PFUser.currentUser().saveInBackground()
println("Added with getFirstObject")
}
else{
println("Error Added with getFirstObject")
}
}
}
UPDATE 2:
Messages without PFRelation:
Add a column (let's say user) of type Pointer with Target Class as _User to the Messages table to identify each message by their user.
Saving new messages: Save the new message object like above (just without adding the relation and it'e related code):
#IBAction func addMessage(sender: AnyObject) {
var newMessage = addMessageText.text
let message = PFObject(className: "Messages")
message["messageTextColumn"] = newMessage
message["user"] = PFUser.currentUser()
message.saveInBackgroundWithBlock {(success: Bool, error: NSError?) -> Void in
if (success) {
println("added to Message Class")
} else {
// Error saving message
}
}
}
Querying the messages for a user: You can query using the current user as a constraint so no matter which device a particular switches to, he/she will get only his messages.
var query = PFQuery(className:"Messages")
query.whereKey("user", equalTo:PFUser.currentUser())
query.findObjectsInBackgroundWithBlock {
...
}