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).
Related
I've been trying to retrieve the username for a certain user from a user object in Parse. One of the queries i tried to to that with looks like this:
let query = PFQuery(className: "User")
query.whereKey("objectId", equalTo: userId!)
query.findObjectsInBackgroundWithBlock{(objects:[PFObject]?, error: NSError?) -> Void in
if error == nil {
for object in objects! {
self.username.text = String(object["username"])
}
}
}
Is there another way to do this? I'm really new to working with Parse and I really haven't found a way to make this work yet..
When querying the user table, use PFUser.query() to construct your query rather than PFQuery(className: "User")
let query = PFUser.query()
query.whereKey("objectId",equalTo: userId!)
query.findFirstObjectInBackgroundWithBlock{(object,error)->Void in
if error == nil{
if let user = object as? PFUser{
self.username.text = user.username;
}
}
}
I have an app where I'm trying to load a User and all his related data. In the relations I have BodyTracking as one relation. Another is DiaryWeek, which in turn has DiaryDays (of the week).
I successfully pulled all the BodyTracking, but when I try the same for the DiaryWeeks, I get an error saying that I have to wait. I guess what is happening is that the BodyTracking, which is requested with 'findObjectsInBackgroundWithBlock' is still going on when the DiaryWeek request is called.
Is there a way to pull all the data in one go?
// Body Tracking
bodyEntries.removeAll()
let trackingQuery = PFQuery(className: "BodyTracking")
trackingQuery.whereKey("user", equalTo: member)
trackingQuery.orderByDescending("trackingDate")
trackingQuery.findObjectsInBackgroundWithBlock {
(objects: [PFObject]?, error: NSError?) -> Void in
if error == nil {
print("Successfully retrieved \(objects!.count) body entries.")
if let objects = objects! as? [PFObject] {
for object in objects {
let bodyEntry = BodyTracking(object: object)
self.bodyEntries.append(bodyEntry)
}
self.bodyTrackingTableView.reloadData()
}
} else {
// Log details of the failure
print("Error: \(error!) \(error!.userInfo)")
}
}
// Food Diary
foodWeeks.removeAll()
let diaryQuery = PFQuery(className: "FoodDiaryWeek")
diaryQuery.whereKey("user", equalTo: member)
diaryQuery.orderByDescending("weekStartDate")
trackingQuery.findObjectsInBackgroundWithBlock {
(objects: [PFObject]?, error: NSError?) -> Void in
if error == nil {
print("Successfully retrieved \(objects!.count) food weeks")
if let objects = objects! as? [PFObject] {
for object in objects {
let foodWeek = FoodDiaryWeek(object: object)
self.foodWeeks.append(foodWeek)
}
}
} else {
// Log details of the failure
print("Error: \(error!) \(error!.userInfo)")
}
}
Error message: This query has an outstanding network connection. You have to wait until it's done.
It looks like you are accidentally executing the trackingQuery twice. The diaryQuery is never executed. Maybe a copy/paste error (?)
// Food Diary
foodWeeks.removeAll()
let diaryQuery = PFQuery(className: "FoodDiaryWeek")
diaryQuery.whereKey("user", equalTo: member)
diaryQuery.orderByDescending("weekStartDate")
**trackingQuery**.findObjectsInBackgroundWithBlock {
replace trackingQuery by diaryQuery
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()
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.")
}
}
}