I am working with Parse for the first time in my application, and everything seems to be working well with the exception of when I go to change existing data. I am simply trying to change a string value that I have stored in a column of one of my items.
This is the code I currently have:
func sendTimeToParse() {
var query = PFQuery(className: "ClassName")
query.whereKey("Name", equalTo: rideNamePassed)
query.getFirstObjectInBackgroundWithBlock {
(object: PFObject?, error: NSError?) -> Void in
if error != nil {
println("The getFirstObject request failed.")
} else {
// The find succeeded.
let object = PFObject(className: "ClassName")
object.setValue(self.timeSelected, forKey: "WaitTime")
object.saveInBackground()
println("Successfully retrieved the object.")
}
}
}
}
At the moment it just seems to create a new row of data and saves the time to that, however obviously I would like it to change the existing data in whatever row matches the name of the current record.
Anyone have any suggestions?
The problem is that you are creating a new PFObject with the line let object = PFObject(className: "ClassName") instead of using the retrieved object which is given as a parameter.
Simply delete the line let object = PFObject(className: "ClassName") and unwrap the received optional. It could look something like the following:
func sendTimeToParse() {
var query = PFQuery(className: "ClassName")
query.whereKey("Name", equalTo: rideNamePassed)
query.getFirstObjectInBackgroundWithBlock {
(object: PFObject?, error: NSError?) -> Void in
if error != nil {
println("The getFirstObject request failed.")
} else {
if let obj = object {
obj.setValue(self.timeSelected, forKey: "WaitTime")
obj.saveInBackground()
}
println("Successfully retrieved the object.")
}
}
}
Related
I am trying to delete an object from the class UserRequests via swift only if the object belongs to the current user, and that requestResponded is not equal to true. However, I get an error at objects.deleteInBackground() and the function still doesn't work when I remove this line.
func deleteRequest(){
let check = PFQuery(className: "UserRequests")
check.whereKey("requestResponded", equalTo: "True")
let query = PFQuery(className: "UserRequests")
query.whereKey("username", equalTo: (PFUser.currentUser()?.objectForKey("username") as! String))
query.findObjectsInBackgroundWithBlock({ (objects, error) -> Void in
if objects != nil && error == nil{
// Successfully retrieved the object
check.getFirstObjectInBackgroundWithBlock {
(object: PFObject?, error: NSError?) -> Void in
if error != nil || object == nil {
print("Not accepted.")
object!.deleteInBackground()
objects.deleteInBackground()
} else {
print("Successfully retrieved the object.")
}
}
}else{
self.performSegueWithIdentifier("requestAccepted", sender: self)
}
})
}
It is because objects is an list of object. You should only delete object 1 by 1.
For example:
for object in objects {
object.deleteInBackground()
}
Also, because two queries belong to same class. I would suggest using 1 query
UPDATE
func deleteRequest(){
let query = PFQuery(className: "UserRequests")
// the key "requestResponded" is not True
query.whereKey("requestResponded", equalTo: "False")
// for deleting the object is that it belongs to the current user
query.whereKey("username", equalTo (PFUser.currentUser()?.objectForKey("username") as! String))
query.findObjectsInBackgroundWithBlock({ (objects, error) -> Void in
if error != nil{
print(error)
}
// objects are those the key "requestResponded" is not True and belongs to the current user
for object in objects {
object.deleteInBackground()
}
// other case
if objects.count == 0 { // no match result found
}
})
}
I guess you still miss the condition of when to perform segue
I have a class named Post which stored the data of Image, Text and the upLoader.
The uploader is link or a pointer to the User class.
When I was testing
When the current user is equal to the user which is pointed, everything is good. However, when the current user is not equal to the uploader, I cannot got the data from the uploader such as username and email. The only data I could retrieve is [ {
}]
Code of Query
let query = PFQuery(className:"Post")
query.orderByDescending("createdAt")
query.findObjectsInBackgroundWithBlock {
(objects: [PFObject]?, error: NSError?) -> Void in
if error == nil {
print("Successfully retrieved \(objects!.count) scores.")
if let objects = objects! as [PFObject]! {
for object in objects {
self.message.append(object["message"] as! String)
self.imageFiles.append(object["imageFile"] as! PFFile)
self.user.append(object["upLoader"] as! PFUser )
self.createdAT.append(object.createdAt!)
self.tableView.reloadData()
}
}
} else {
print("Error: \(error!) \(error!.userInfo)")
}
Can anyone help me?
Thanks
By default, Parse queries don't include the actual objects that are referenced by pointers, so your upLoader is just a reference to the object ID, not the actual object. To include the actual object, you just need to add includeKey to your query. For example:
let query = PFQuery(className:"Post")
query.includeKey("upLoader") // This should do the trick.
query.orderByDescending("createdAt")
query.findObjectsInBackgroundWithBlock {
(objects: [PFObject]?, error: NSError?) -> Void in
if error == nil {
print("Successfully retrieved \(objects!.count) scores.")
if let returnedObjects = objects {
for object in returnedObjects {
self.message.append(object["message"] as! String)
self.imageFiles.append(object["imageFile"] as! PFFile)
self.user.append(object["upLoader"] as! PFUser )
self.createdAT.append(object.createdAt!)
dispach_async(dispatch_get_main_queue(), { () -> Void in
//UI stuff need to be on main thread
self.tableView.reloadData()
})
}
}
} else {
print("Error: \(error!) \(error!.userInfo)")
}
}
Several days I'm trying to crack why my code doesn't work and everything I've tried doesn't give me any result. Heres the deal:
There is a Booking class that contains userFrom who made booking
let query = PFQuery(className: "Booking")
query.whereKey("offer", equalTo: offer.pfObject!)
if self.typeOfUser == .COOK { //! If user is a Cook
query.findObjectsInBackgroundWithBlock({ (objects : [PFObject]?, error : NSError?) -> Void in
if let error = error {
print(error.localizedDescription)
} else {
if let objects = objects {
self.bookings = objects
self.usersIds = [String]()
for object in objects {
let userFrom = object.objectForKey("userFrom") as? PFObject
let userId = userFrom!.objectId! as String
self.usersIds.append(userId)
}
self.getUserInfoForBooking()
} else {
print("Something went wrong")
}
}
})
}
From every user I get objectId and append it to the [String] array. Then I query users with their IDs
private func getUserInfoForBooking() {
let userQuery = PFQuery(className: "User")
userQuery.whereKey("objectId", containedIn: self.usersIds)
userQuery.findObjectsInBackgroundWithBlock({ (objects : [PFObject]?, error : NSError?) -> Void in
if let error = error {
print(error.localizedDescription)
} else {
print(objects!)
if let objects = objects {
for object in objects {
self.users.append(object)
}
self.collectionView.reloadData()
}
}
})
}
In this query I always get an empty array.
Whatever I did, whatever I've changed always [] in response :(
This is the wrong way to query users
let userQuery = PFQuery(className: "User")
Because the class name is private. You should be creating the query as
let userQuery = PFUser.query()
How can I use a query to find the currentUser from a Parse Class and then write data into that user columns?
var query = PFQuery(className:"User")
query.whereKey("objectId", equalTo:PFUser.currentUser()!)
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
// The find succeeded.
println("Successfully retrieved \(objects!.count) scores.")
// Do something with the found objects
if let objects = objects as? [PFObject] {
for object in objects {
println(object.objectId)
}
}
} else {
// Log details of the failure
println("Error: \(error!) \(error!.userInfo!)")
}
}
Change this line
query.whereKey("objectId", equalTo:PFUser.currentUser()!)
To:
query.whereKey("objectId", equalTo:PFUser.currentUser().objectId)
And also if you are querying from the parse user class it should be _User not User
To Only save data
var ObjectToSave = PFObject(className: "_User")
ObjectToSave["raw"] = "whateveryoulike"
ObjectToSave["UserId"] = PFUser.currentUser()?.objectId // this piece of code is when you create a new class
ObjectToSave.saveInBackgroundWithBlock { (success:Bool, error:NSError?) -> Void in
if error == nil{
println("data was saved")
}
else
{
println("error")
}
}
}
I don't think it is a good idea to save other data into the _User class, you should leave this class for the login or sign up. You should create a new class then save all new data with the userid...
you don't need to query for the current user.
Use this
var user = PFUser.currentUser()
user["one"] = "whateveryoulike"
user["two"] = "whateveryoulike"
user.saveInBackgroundWithBlock { (success:Bool, error:NSError?) -> Void in
if error == nil{
println("data was saved")
}
else
{
println("error")
}
}
}
I'm using Parse
I have a "Post" class with fields.
Post class have some field, and one of it is "user" linked with "User" class
I want query Post class and get all the users in the response.
let query = PFQuery(className: "Post")
// How to get all user in the post class
Is there another way like..
let query = PFQuery(className: "Post")
let usersQuery = PFUser.query()
usersQuery.whereKey("SELF", matchesKey: "user", inQuery: query)
But I know there is no SELF keyword
Objective C is also fine
Given this page in the Parse documentation, it should look something like this:
let query = PFQuery(className: "Post")
query.findObjectsInBackground() { posts, error in
if (!error) {
for post in posts {
let user = post["user"]
println("User: \(user)")
}
} else {
// Log details of the failure
println("Error: \(error), \(error.userInfo)")
}
}
In Parse you use a PFQuery to query the database..
In a callback (asynchronusly) you get a PFObject or an array of PFObjects.
How to do this is written in their guide
Here's a little example:
You can get all properties/fields whatever by calling the array function on the PFObject.
var pfObject = PFObject()
pfObject["yourcolumn"] as? String //Whatever you want
In your case a PFUser would be the solution
pfObject["yourusercolumn"] as? PFUser
To query you use a PFQuery
Asynchronusly (preffered):
var query = PFQuery(className:"GameScore")
query.whereKey("playerName", equalTo:"Sean Plott")
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
// The find succeeded.
println("Successfully retrieved \(objects!.count) scores.")
// Do something with the found objects
if let objects = objects as? [PFObject] {
for object in objects {
println(object.objectId)
}
}
} else {
// Log details of the failure
println("Error: \(error!) \(error!.userInfo!)")
}
}
Synchronusly:
var query = PFQuery(className:"GameScore")
var objects = query.findObjects()
for object in objects {
// Do whatever you want with your pfobject
}
Asynchronus queries are more likely because they don't run on the GUI thread what makes your app way more faster (on the UI).