swift parse query get last createdAt objects - ios

I have did a lot of querys, searched in websites , And already asked this question before and i didn't found a good answer!
I have Parse backend looks like this:
In my view controller I just want to show Last createdAt for each sender
i want to get all the row of last object for sender:.
so we should ignore "name1: Hello" and "name2: Really when was.." because this old rows we already got new objects.
I want one result for each sender depends on createdAt
so can I get help with query to do this? or how can we do that?
let query = PFQuery(className: "test")
query.whereKey("receivers", equalTo: PFUser.currentUser()!.username!)
query.orderByDescending("createdAt")
query.findObjectsInBackgroundWithBlock {
(objects, error) -> Void in
if error == nil {
// now what? I've done everything i could none worked fine
I hope if i'll get a help to do that, So please help me if you could.

you can just add a limit to the query.. see parse docs..
let query = PFQuery(className: "test")
query.whereKey("receivers", equalTo: PFUser.currentUser()!.username!)
query.orderByDescending("createdAt")
query.limit = 1
query.findObjectsInBackgroundWithBlock {
(objects, error) -> Void in
if error == nil {

Your data model isn't really suitable for doing this operation quickly. But, how you setup your data model is dictated by all of your requirements, not just one.
To make this easy you should add a pointer from your User to your Message, and every time a message is sent by a user you set that pointer (which replaces the old pointer).
Now, you can simply query Users, using includeKey to get the message, and display your list.

Related

Swift: Multiple Parse Query from one class

I have a Parse Class named friendRequest where keys are requestFrom & requestTo which contains unique ids of people who have sent request and received them respectively.
I have a user for whom I need to fetch friend requests which have been sent to him and received by him to find out the status of the request.
I am trying to combine two queries where I match the user's id in requestFrom & requestTo keys and fetch all the results where the condition is true. I get 0 values in return.
My code is:
let friendsQuery : PFQuery = PFQuery(className: "friendRequest")
let objectId = PFUser.current()?.objectId
friendsQuery.whereKey("requestFrom", equalTo: objectId!)
friendsQuery.whereKey("requestTo", equalTo: objectId!)
friendsQuery.findObjectsInBackground(block: { (objects, error) in
//code
})
How should I combine the queries to get the desired results?

Parse PFQuery bug with geoPoint constraint

I am doing a pretty straightforward PFQuery. I want to get any objects where the specific key I'm entering exists, and the object is within 2 km of user location. However, this query returns all objects within 2 km, but doesn't filter out anything to only return objects where that key exists. I checked and the key ("T(objectIDs[0])") contains the information I think it does. Additionally, I have tried this in a compound query where I am doing a different key in each query. This query works as expected and returns objects within 2 km AND only where the key exists. Have any of you seen behavior like this? Any insight is greatly appreciated, thanks!
let singleQuery = PFQuery(className: locationTagsClassNameConstant)
singleQuery.whereKeyExists("T\(objectIDs[0])")
singleQuery.whereKey(geoPointColumnNameConstant, nearGeoPoint: userGeo, withinKilometers: 2)
singleQuery.findObjectsInBackgroundWithBlock({ (objects, error) -> Void in
if error == nil {
var dataToExtract:Array<AnyObject> = []
if let objects = objects {
for activity in objects {
dataToExtract.append(activity)
}
complete(result: dataToExtract)
}
} else {
// Log details of the failure
print("Error++++: \(error!)")
}
})

Check if query key is nil Parse

So, I have a query in parse that has to find objects based on whether a key is equal to a certain object. Here is the few lines of code.
var gamesQuery = PFQuery(className: "Games")
gamesQuery.whereKey("challenged", equalTo: (PFUser.currentUser()!.objectId!))
gamesQuery.whereKey("challenger", equalTo: PFUser.currentUser()!)
However, when this query is ran, the query is occasionally found as nil due to the fact that there is no object that fits the search parameters.
Is there any check that I could run that could check if
gamesQuery.whereKey("challenged", equalTo: (PFUser.currentUser()!.objectId!))
is nil? Any help with this issue would be very appreciated.
Your current query is essentially an and - "find objects where challenged==current user and challenger==current user".
I think you are after an or query - "find objects where challenged==current user or challenger==current user". You can do this with a compound query in Parse -
let challengedQuery = PFQuery(className: "Games")
challengedQuery.whereKey("challenged", equalTo: (PFUser.currentUser()!.objectId!))
let challengerQuery = PFQuery(className: "Games")
challengerQuery.whereKey("challenger", equalTo: PFUser.currentUser()!)
let gamesQuery = PFQuery.orQueryWithSubqueries([challengedQuery, challengerQuery])
gamesQuery.findObjectsInBackgroundWithBlock {
(results: [PFObject]?, error: NSError?) -> Void in
if error == nil {
// results contains challenger and challenged games.
}
}

Combining queried objects into a single array. Code finds followed users then their posts, it returns the posts separately per user, how to combine?

The code below queries "followers" to see if a user is following another and then if they are it queries "Post" to find post from the users they are following. Currently the logged in user is following 2 other users, user A and user B. A has 1 post and B has 2 posts. For some reason when I run the second set of codes below, it returns the counts separately. The println shows the post count by individual user. I need the count to be the sum of all posts found. It seems that there is 2 arrays of posts because there are 2 users followed. How do I combine these 2 arrays?
var getFollowedUsersQuery = PFQuery(className: "followers")
getFollowedUsersQuery.whereKey("follower", equalTo: PFUser.currentUser()!.objectId!)
getFollowedUsersQuery.findObjectsInBackgroundWithBlock { (objectos, error) -> Void in
if let objectos = objectos {
for objecto in objectos {
var followedUser = objecto["following"] as! String
var query = PFQuery(className: "Post")
query.whereKey("userId", notEqualTo: currentuser.objectId)
query.whereKey("userId", equalTo: followedUser)
query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]!, error:NSError!) -> Void in
if error == nil {
self.postsArray.removeAllObjects()
self.postsFound.removeAllObjects()
let array:NSMutableArray = NSMutableArray(array: objects)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(2 * Double(NSEC_PER_SEC)))
dispatch_after(time, dispatch_get_main_queue() , { () -> Void in
fn(array)
})
} else {
println(error.localizedDescription)
}
And when I run
self.postsFound.addObjectsFromArray(array as [AnyObject])
self.totalUsers = self.postsFound.count
println("Total Posts found \(self.postsFound.count)")
The println is returning:
Total Posts found 1
Total Posts found 2
I want all the posts found to be in 1 array and have the println return:
Total Posts found 3
The best option from a query point of view would be to make only 1 query and include your followers query as a requirement of that query. In this way you would be asking for all of the posts whose author is a followed user. This is looking at the problem backwards compared to find all followed users and then find their posts. As its a composite request it's more efficient and returns a single list.
Note that there are limitations... Yhe inner query will be limited to 1000 followers (100 by default), and you would need to add a sort to get sensible results from the outer query.
Continuing with your current query setup can help you avoid these query limit restrictions, but you need to organise building a single array of results yourself. It would be best to do that in cloud code and use promises to wait for all of the requests to complete.
This is all quite general I'm afraid, but you need to decide on an appropriate approach depending on what you're actually using this data for and how many users you're expecting to have...

ios swift parse: Having general issues with deep queries and their result data

I am still having problems understanding the correct way of handling deeper pointer structure in parse.
Example:
Card has pointer to CardSet
CardSet has pointers to Lesson and User
Lets say, I want to have all CardSets including
Lesson.name
Count of Cards for each CardSet
Can I query all this in just one query?
And have the data available without any additional fetchIfNeededInBackgroundWithBlock queries?
I know that I can get the Lesson with
var query = PFQuery(className: "CardSet")
query.whereKey("user", equalTo: PFUser.currentUser())
query.includeKey("lesson")
But that gives me only the lesson object, I can not access any data (like the col "name") from this class unless I use fetchIfNeededInBackgroundWithBlock what takes another query and of course more time to load.
What can I do to have all queried data
including all pointers columns
in order to pin this data to the local datastore with
PFObject.pinAllInBackground(objects, block: nil)
And not to forget, how can I query the number of cards related to the CardSet?
First I would recommend subclassing in Parse, it makes relationships between tables (pointers etc) clearer.
How to subclass the PFObjects you can explore this guide on parse
How to query the number of cards in CardSet
You need the CardSet from which you want the cards. (PFObject or subclassed PFObject).
Then just do this:
var query = PFQuery(classname: "cards")
query.whereKey("CardSet", equalTo: yourCardSetObject)
//Synchronously
query.findObjects().count
//Asynchronously
query.findObjectsInBackgroundWithBlock({
(objects, error) in
if error != nil {
println(error.localizedDescription)
return
}
objects.count
})
How to get the name of the lesson
As I said, it's recommended to subclass the PFObjects because you need to cast the objects what isn't really funny to debug and is horrible code.
I did it that way:
var query = PFQuery(className: "CardSet")
query.whereKey("user", equalTo: PFUser.currentUser())
query.includeKey("lesson")
query.findObjectsInBackgroundWithBlock({
(objects, error) in
if error != nil {
println(error.localizedDescription)
return
}
for object in objects as? [PFObject] {
var lesson = object["lesson"] as PFObject
println(lesson["name"])
}
})

Resources