How to get a query retrieving two objects from Parse via Swift - ios

I have a parse database as in the picture.
I need to retrieve with a query code, two objects, for example the last created dates of type 2 and 3.
I am trying the codes below, but dont know how to merge these two queries (query2 and query3)? Or might there be another way to retrieve these two objects as one table?
var query2 = PFQuery(className: "stories")
query2.whereKey("Type", equalTo: 2)
query2.addDescendingOrder("createdAt")
query2.getFirstObject()
var query3 = PFQuery(className: "stories")
query3.whereKey("Type", equalTo: 3)
query3.addDescendingOrder("createdAt")
query3.getFirstObject()

I don't think you could do exactly what you currently have with 1 query. You could combine them but only to get back an array of all 2 and 3 types and then split them out yourself.
If the issue is making 2 different network requests then you could create a cloud code function to run the 2 queries and return the results in a single response.

you can do this one query as well
var query2 = PFQuery(className: "stories")
query2.whereKey("Type", equalTo: 2)
query2.whereKey("Type", equalTo: 3)
query2.addDescendingOrder("createdAt")
You can change you approach too , you can send array to compare and sort results
query2.whereKey("Type", containedIn: #[2,3])
query2.addDescendingOrder("createdAt")
After this don't use getFirstObject ; get all array and get your desired results using predicate or any else , this will save one network call as well.
This is for getting 2 values from Array
NSArray *fullArray= All objects from the parse ;
NSMutableArray *selectedObjectsArray = [NSMutableArray array];
for(int i=0 ; i<fullArray.count ; i++){
if (selectedObjectsArray.count==1 && ![[[selectedObjectsArray objectAtIndex:0] objcetForKey:#"type"] isEqualToString:[[Full array objectAtIndex:i] objcetForKey:#"type"]]) {
[selectedObjectsArray addObject:[fullArray objectAtIndex]];
break ;
}else{
[selectedObjectsArray addObject:[fullArray objectAtIndex]];
}
}
In Swift (i m not too good in swift so double check swift code before using)
for object in fullArray {
if (selectedObjectsArray.count==1 && ![[selectedObjectsArray[0][#"type"] isEqualToString:fullArray[i][#"type"]) {
selectedObjectsArray[1]=[fullArray[i];
break ;
}else{
selectedObjectsArray[0]=[fullArray[i];
}
}

Related

Adding integers in for loop and printing the total

I am looping through integer objects and want to add each integer to an integer variable, then when the for-loop is done, print the total. Is there an easy way to do this? Right now, I can retrieve the objects and print them individually, but the total prints as 0 every time.
Please see the code below. This is for an app written in Swift with Parse as the backend.
Anything helps, and thank you!
var itemsArray = [Int]()
let followingUserItemsQuery = PFUser.query()
followingUserItemsQuery?.whereKey("objectId", equalTo: (PFUser.currentUser()?.objectId!)!)
followingUserItemsQuery?.findObjectsInBackgroundWithBlock({ (objects: [PFObject]?, error) in
if let objects = objects {
for object in objects {
let followingUsersArray = (object["following"] as! [String])
// Get number of listed items of following users with PFUser query for their total objects
for followingUser in followingUsersArray {
print(followingUser)
let query = PFUser.query()
query?.whereKey("objectId", equalTo: followingUser)
//Get each user's listedItems count then append to a higher-level integer variable
query?.getFirstObjectInBackgroundWithBlock({ (object, error) in
itemsArray.append(object!["listedItems"] as! Int)
})
}
}
}
let itemsSum = itemsArray.reduce(0, combine: +)
print(itemsSum)
self.followingUsersAddedItems.text = String("Your followers listed "+String(itemsSum)+" items")
Try this:
var count = 0
...
for followingUser in followingUsersArray {
count += object!["listedItems"] as! Int
}
Your code to reduce / combine the Int values is correct. The problem is that it runs before any of the nested asynchronous Parse queries complete and execute their callbacks. So at the time it runs, itemsArray is still empty. You will need to redesign your code so that itemsSum is calculated only after all the various nested Parse queries have all completed.

Compare and Match Array Values

When the user searches for a category I need all the arrays that contain that same category to appear + the other categories that are in that respective array.
Once the user has chosen ["Apples", "Oranges", "Limes"] I want to compare which array (out of many) that I queried contains Apples, Oranges or Limes. This can be one array or this can be many arrays.
These are the arrays I'm adding the values to:
var categoryNeeded = [AnyObject]() //The user creates this one and adds values to it
var categoryArr = [AnyObject]() //The Parse arrays are added here:
I have a simple Parse query function.
var query : PFQuery = PFUser.query()!
query.whereKey("contacts", containsString: "\(categoryArr)")
query.findObjectsInBackgroundWithBlock { (objects, error) -> Void in
if let objects = objects as [PFObject]! {
for object in objects {
self.categoryArr.append(object["contacts"] as! AnyObject)
print(self.categoryArr)
}
}
}
The 2nd line is suspect:
query.whereKey("contacts", containsString: "\(categoryArr)")
When querying with that line, I get this error (without a crash):
2016-01-23 15:53:47.508 CC[28514:5733236] [Error]: $regex only works
on string fields (Code: 102, Version: 1.11.0)
Without the whereKey line, I get all the values and it prints them. I just can't figure out how to compare and check for matches between the two arrays which ultimately gives the matching arrays. Is there a Swift method that does that?
You should not use containsString but rather containedIn:
query.whereKey("contacts", containedIn: categoryArr)

PFQueryTableViewController - Getting different objects

I've two Parse tables, Users and Evaluations that are connected by a pointer reference to User.ref (a pointer to itself) -> Evaluations.evaluatedId (a user pointer)
In my PFQueryTableViewController I need to get all users list with their last evaluation. I'm trying with:
override func queryForTable() -> PFQuery
{
let userQuery = PFUser.query()!
let evaluationQuery = PFQuery(className: "Evaluations")
evaluationQuery.whereKey("evaluatorId", matchesKey: "ref", inQuery: userQuery)
let query = PFQuery.orQueryWithSubqueries([userQuery, evaluationQuery])
query.cachePolicy = PFCachePolicy.CacheThenNetwork
return query
}
But I'm getting this error:
'All sub queries of an or query should be on the same class.'
I've searched for a while and I found this:
When using orQueryWithSubqueries, each subquery should be for the same class. If you need to query different classes, you will need either a separate query for each, or use whereKey:matchesQuery: if the other class is pointed to by the parent class.
Any suggestions? Thanks in advance!

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...

Parse get all the objects from a pointer column

I want to get all the objects in a pointer column from a query. I have a object class named A that contains a pointer column to object B. (Only 1 object) I have a query for A and I want to get all the B objects from that query. So I'm trying to do something like this...
var queryA = PFQuery(classname: "A");
queryA.whereKey("level", equalTo: 1);
var queryB = PFQuery(classname: "B);// not sure if this is necessary
//here I couldn't find anything, this should be something like
//get objects from queryA's "objectB" column
//After merging the column key with queryB (assuming I can)
queryB.whereKey("games", lessThan: 5); //I add constraints
When I try to use queryB.whereKey("key", matchesKey: "objectB", inQuery: queryA) it doesn't work because the "objectB" key points to the B objects not a key in it. Do you guys have any ideas? (Any answer is greatly appreciated. I can understand Objective-C as well as Swift)
You can do this with the includeKey() method. It will get the related data for the pointer column.
var queryA = PFQuery(classname: "A");
queryA.whereKey("level", equalTo: 1);
query.includeKey("columnName");
The second query (queryB) is not necessary.

Resources