Combind parse queries and add to seperate arrays - ios

How can I combine multiple Parse Queries?
I want to query the column sclink and songTitle from parse.com then add each to its own array.
Also how to save query locally and call it? IF else statment or something:
NSMutableArray *trackList = [[NSMutableArray alloc] init];
PFQuery *queryTracks = [PFQuery queryWithClassName:#"liveRadioPL"];
NSArray *objects = [queryTracks findObjects]; // Online PFQuery results
[PFObject pinAllInBackground:objects];
[queryTracks selectKeys:#[#"scLink"]];
[queryTracks findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// The find succeeded.
totalTracks = (int)objects.count;
NSLog(#"Successfully retrieved %lu Tracks.", (unsigned long)objects.count);
// Do something with the found objects
for (PFObject *object in objects) {
[trackList addObject:[NSString stringWithFormat:#"%#", [object objectForKey:#"scLink"]]];
}
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
trackListArray = trackList;
NSMutableArray *trackTitles = [[NSMutableArray alloc] init];
PFQuery *queryTitles = [PFQuery queryWithClassName:#"liveRadioPL"];
NSArray *objectsTitle = [queryTitles findObjects]; // Online PFQuery results
[PFObject pinAllInBackground:objects];
[queryTracks selectKeys:#[#"songTitle"]];
[queryTracks findObjectsInBackgroundWithBlock:^(NSArray *objectsTitle, NSError *error) {
if (!error) {
// The find succeeded.
totalTitles = (int)objectsTitle.count;
NSLog(#"Successfully retrieved %lu Titles.", (unsigned long)objectsTitle.count);
// Do something with the found objects
for (PFObject *object in objects) {
[trackTitles addObject:[NSString stringWithFormat:#"%#", [object objectForKey:#"songTitle"]]];
}
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];

I'm not sure your logic really makes sense - you're using 4 API requests when all you need is 1 API request. Also, Jacob is right, you're filling an array from a background thread and as a result the main thread will see it as empty.
I think I understand what you're trying to do - try this
PFQuery *queryTracks = [PFQuery queryWithClassName:#"liveRadioPL"];
// use includeKey if slink and songTitle are pointers to other Parse classes
// from the context of your question you probably don't need to use includeKey
[queryTracks includeKey:"scLink"];
[queryTracks includeKey:"songTitle"];
NSArray *objects = [queryTracks findObjects];
NSMutableArray* scLinks = [[NSMutableArray alloc] init];
NSMutableArray* songTitles = [[NSMutableArray alloc] init];
for (PFObject* object in objects) {
[scLinks addObject:object[#"scLink"]];
[songTitles addObject:object[#"songTitles"]];
}
I hope this helps, good luck!

Related

Parse.com WhereKey:containedIn doesn`t show any results - objectId

I have UITableView with data taken from Parse.com. When I tried to filter them according to the NSArray, it does not show any results. Without the whereKey:containedIn, everything works fine. NSArray *array returns array of strings well. So the problem must be in the method containedIn, any ideas?
PFUser *user = [PFUser currentUser];
NSArray *array = [[PFUser currentUser] objectForKey:#"favorites"];
NSLog(#"ARR:%#", array);
if (user) {
quer = [PFQuery queryWithClassName:#"bs"];
[quer whereKey:#"objectId" containedIn:array];
[quer findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
self.itemss = [objects mutableCopy];
NSLog(#"KOL::%lu", (unsigned long)[objects count]);
[self.MainTable reloadData];
if (objects.count ==0) {
} else {
}
} else {
[quer cancel];
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
} else {
NSLog(#"no");
}
}
The array of "favorites" is an array of favorite objects when I'm sure it should be an array of objectIds. If you create an array that contains the objectIds of the favorite objects then it should work.

Display the username of query results (Parse.com on iOS)

I am currently using the query whereKey:#"name" equalTo:#"Tom Coomer" and it is working.
However I would like to create an array of the usernames from the results.
How would I approach this?
Thanks
I am using Parse.com and Xcode to write the app.
Well, I assume you're saving your query results to an array, so what you want to do is this:
NSMutableArray *array = [NSMutableArray array]
for(PFUser *user in arrayFromQuery)
{
[array addObject:user.username];
}
What this does is traverse through your array and gets the username from each user and adds it to a new array.
If you want to fetch only the username from the Parse :
PFQuery *query = [PFQuery queryWithClassName:#"_User"];
[query selectKeys:#[#"username"]];
[query findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error) {
// objects in results will only contain the username fields
}];
result array contains the name of all user.
And if u want to fetch all records and then create a array of username:
PFQuery *query = [PFQuery queryWithClassName:#"_User"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// The find succeeded.
NSLog(#"Successfully retrieved %d user.", objects.count);
// Do something with the found objects
for (PFUser *object in objects)
{
[self.usernameArray addObject:object.username];
NSLog(#"%#", object.objectId);
}
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
where usernameArray is a NSMutableArray.

Perform action after findObjectsInBackgroundWithBlock completed in for loop

I have such construction in my code:
for (METMeetingEntity *e in self.meetingList) {
PFQuery *query = [PFUser query];
//some query constraints, depending on METMeetingEntity
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error)
{
// some query actions
NSArray *sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"date" ascending:YES]];
self.meetingList = [NSMutableArray arrayWithArray:[self.meetingList sortedArrayUsingDescriptors:sortDescriptors]];
self.meetingList = [self dateCleanup:self.meetingList];
}];
How can I perform action - reload my table view after all the findObjectsInBackground are completed
One possible solution would be to keep a count. When the number matches the original count, you know you are done.
NSUInteger count = self.meetingList.count;
for (METMeetingEntity *e in self.meetingList) {
PFQuery *query = [PFUser query];
//some query constraints, depending on METMeetingEntity
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
// some query actions
NSArray *sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"date" ascending:YES]];
self.meetingList = [NSMutableArray arrayWithArray:[self.meetingList sortedArrayUsingDescriptors:sortDescriptors]];
self.meetingList = [self dateCleanup:self.meetingList];
count--;
if (count == 0) {
dispatch_async(dispatch_get_main_queue(), ^{
// reload table or whatever needs to be done
});
}
}];
}
I think you don't need calling dispatch_async. All the blocks in Parse run in the main thread. In Parse doc you can read:
Both findObjectsInBackgroundWithBlock: and
findObjectsInBackgroundWithTarget:selector: work similarly in that
they assure the network request is done without blocking, and run the
block/callback in the main thread.
This is an example of a query for a UICollectionView:
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if(!error) {
listaFiguras = [objects mutableCopy];
[_collectionView reloadData];
} else {
NSLog(#"Something wrong. No Data.");
}
}];

Displaying Username - Parse

I have looked ALL over the internet and found nothing, Please help me. Im trying to figure out how I can display a username from parse in my table view (detailTextLabel). When I do the code below my app only shows the PFUser Id not the username. It will display: <PFUser:H2AhEbYGal:(null)> { but I'm trying to display the username of that post.
Heres me saving the object:
PFUser *user = [PFUser currentUser];
PFObject *quoteNew = [PFObject objectWithClassName:#"New"];
quoteNew[#"author"] = user;
[quoteNew setObject:[[self quoteText] text] forKey:#"quoteText"];
Here is me trying to retrieve the user in a PFQuery:
PFQuery *query = [PFQuery queryWithClassName:#"New"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// The find succeeded. The first 100 objects are available in objects'
[query includeKey:#"author"];
// PFObject *testObject = [query findObjects];
// PFUser *testUser = [testObject objectForKey:#"author"];
// NSLog(#"username: %#",testUser.username);
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
Here is me trying to display it:
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#: %#",[object objectForKey:#"author"],[dateFormat stringFromDate:updated]];
You can just worry about [object objectForKey:#"author"] in that cell.detailTextLabel.text code.
This:
PFQuery *query = [PFQuery queryWithClassName:#"New"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// The find succeeded. The first 100 objects are available in objects'
[query includeKey:#"author"];
// PFObject *testObject = [query findObjects];
// PFUser *testUser = [testObject objectForKey:#"author"];
// NSLog(#"username: %#",testUser.username);
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
Should be:
PFQuery *query = [PFQuery queryWithClassName:#"New"];
// BEFORE WE QUERY
[query includeKey:#"author"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// Get your objects here
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
And this:
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#: %#",[object objectForKey:#"author"],[dateFormat stringFromDate:updated]];
Should be:
PFUser *userToDisplay = object[#"author"];
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#: %#",userToDisplay.username,[dateFormat stringFromDate:updated]];
Because, as it stands, problem 1 is you're saying to include the author AFTER you have already queried parse. Problem 2 is that you're trying to display the whole user, you need to get the user, and then print the username value.

pulling a value from NSMutableDictionary

Here's my code for returning a unique value for identical keys in a dictionary. Right now, in my log, my "objects array:" is 6 (3 sets of (2 objects with identical keys)), and my "dictionary:" returns values for 1 object from each set (3 unique values). In my 'for' statement:
for (id key in dict)
{
self.titlesArray = [NSMutableArray arrayWithObject:dict];
NSLog(#"titles: %#", self.titlesArray);
self.titlesArray = [[NSMutableArray alloc] initWithObjects:[dict valueForKey:key] ,nil];
NSLog(#"titles: %#", self.titlesArray);
}
The first log prints out the three unique values AND keys. The second prints only a single value for a single key (which is what I want.. but I need all three key values) So my problem now is that I am unable to pull a key for each unique value from the dictionary and add it to my titlesArray.
for (id key in dict)
{
self.titlesArray = [NSMutableArray arrayWithObject:dict];
self.titlesArray = [[NSMutableArray alloc] initWithObjects:[dict valueForKey:key] ,nil];
code isn't quite right.
PFQuery *query = [PFQuery queryWithClassName:#"Images"];
[query whereKey:#"recipientIds" equalTo:[[PFUser currentUser] objectId]];
[query orderByDescending:#"createdAt"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
NSLog(#"Error: %# %#", error, [error userInfo]);
}
else {
// found messages!
self.objectsArray = objects;
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
for(id obj in self.objectsArray){
PFObject *key = [obj valueForKey:#"titleLabel"];
if(![dict objectForKey:key]){
[dict setValue:key forKey:[obj valueForKey:#"titleLabel"]];
}
}
for (id key in dict) {
self.titlesArray = [NSMutableArray arrayWithObject:dict];
NSLog(#"titles: %#", self.titlesArray);
self.titlesArray = [[NSMutableArray alloc] initWithObjects:[dict valueForKey:key] ,nil];
NSLog(#"titles: %#", self.titlesArray);
}
NSLog(#"dictionary: %#", dict);
NSLog(#"Objects array is %d", [self.objectsArray count]);
[self.pickerView reloadComponent:0];
it looks like there is some type error in line
PFObject *key = [self.objectsArray valueForKey:#"titleLabel"];
it should be
PFObject *key = [obj valueForKey:#"titleLabel"];
It's happening in this line, isn't it:
if(![dict objectForKey:#"titleLabel"]){
[dict setValue:obj forKey:key];
}
}
You are setting "obj" as a value, no problem there, but then you are using "key" which is a PFObject, but NSDictionary requires a NSString for the key.
If PFObject contains a NSString property that you want to use, you can pass that in. For example, if PFObject has an NSString property called "name" you could call this:
if(![dict objectForKey:#"titleLabel"]) {
[dict setValue:obj forKey:key.name];
}
}
The relevant thing to notice is the types of the parameters when NSMutableDictionary defines this method, namely the (NSString*):
- (void)setValue:(id)value forKey:(NSString *)key
How does your PFObject look like. Does it have strings in it?. According to your question you already know that you can't pass a PFObject as key for dictionary. If your object is some what like this
interface PFObject : NSObject
{
NSString *keyString;
......
.Some other variables
}
Then you should be using it like this to set it as key
PFObject *key = [self.objectsArray valueForKey:#"titleLabel"];
if(![dict objectForKey:#"titleLabel"]){
[dict setValue:obj forKey:[key valueForKey#"titleLabel"]];
}
Here is the code I found to work. It takes the array and sorts through the keys to return only unique values for a specific key:
PFQuery *query = [PFQuery queryWithClassName:#"Images"];
[query whereKey:#"recipientIds" equalTo:[[PFUser currentUser] objectId]];
[query orderByDescending:#"createdAt"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
NSLog(#"Error: %# %#", error, [error userInfo]);
}
else {
// found messages!
self.objectsArray = objects;
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
for(id obj in self.objectsArray){
PFObject *key = [obj valueForKey:#"titleLabel"];
if(![dict objectForKey:key]){
[dict setValue:key forKey:[obj valueForKey:#"titleLabel"]];
}
}
for (id key in dict) {
self.titlesArray = [NSMutableArray arrayWithObject:dict];
[self.titlesArray addObject:dict.allKeys];
self.titlesArray = [self.titlesArray objectAtIndex:1];
}
NSLog(#"titles: %#", self.titlesArray);
[self.pickerView reloadComponent:0];

Resources