Count strings inside array - ios

This is my parse.com "currentUploads" class:
Image here
How can I count the amount of strings inside the array? As you can see on the first row, there is 1, and on the last one, it is 3. How can I return this count in a println? I have tried this:
var query = PFQuery(className:"currentUploads")
query.whereKey("objectId", equalTo: post.objID)
query.countObjectsInBackgroundWithBlock {
(count: Int32, error: NSError?) -> Void in
if error == nil {
print("The number is \(count) in total")
}
}
I know there is missing something using the "likedBy", but I dont know where to do what. Any ideas please?

The best way to count all the entries in an array column across all instances (rows) is to iterate the instances in cloud code and count each. This is done simply using the each query and summing up the length of each array then returning the result.
A similar thing can be done on the client, but you'll need to deal with pagination yourself as PFQuery doesn't offer each. In this case you would iterate the objects in each query response and sum the count of each array.

Related

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!)")
}
})

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)

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.

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

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];
}
}

Resources