Here's an interesting one:
I have a UIPickerView that contains the values "10 km", "25 km", "50 km" and "100 km". What ever value is selected will be the value [queryLocation ... withinKilometers: value here ]; is equal too.
Since the value for 'withinKilometers' needs to be a double value, I have the following code to convert the X km to just X as a double value:
if ([self.selectedData isEqualToString:#"10 km"]) {
self.selectedDataConverted = #"10";
self.stringToDouble = [self.selectedDataConverted doubleValue];
NSLog(#"Double Value: %f", self.stringToDouble);
}
... and so on...
and here's the code for the query:
PFQuery *queryLocation = [PFUser query];
[queryLocation whereKey:#"location" nearGeoPoint:self.userLocation withinKilometers:self.stringToDouble];
if (!error) {
NSLog(#"Great Success");
//Do the stuff here
}
else {
NSLog(#"Error");
}
}];
Now when I run this, I get the error [Error]: geo query within or is not supported (Code: 102, Version: 1.7.4). I'm stumped and am not sure how to fix this. Can't find anything similar to my problem either online.
EDIT: I'm starting to think maybe it's because I have connected 2 queries into 1:
PFQuery *finalQuery = [PFQuery orQueryWithSubqueries:#[queryMale, queryLocation]];
[finalQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
NSLog(#"Great Success");
}
else {
NSLog(#"Error");
}
}];
This is to find accounts with the gender 'male' within the desired kilometres at the same time.
You're right. The error geo query within or is not supported means you can't use this query with orQueryWithSubqueries. You will need to run these as 2 separate queries and then combine the result sets yourself.
Related
I would like to retrieve 5 users from Parse, with their latest image posted. But if they haven't posted an image yet, that column will be empty so I have set up my query like this:
func uu() {
let query = PFQuery(className: "_User")
query.includeKey("latestImage")
query.whereKey("username", notEqualTo: PFUser.currentUser()!.username!)
query.findObjectsInBackgroundWithBlock { (object:[PFObject]?, error:NSError?) -> Void in
if error == nil {
for object in object! {
if (object.objectForKey("latestImage") != nil)
{
self.lastPicArray.append(object.objectForKey("latestImage")!.valueForKey("image") as! PFFile)
self.profilePicArray.append(object.valueForKey("profilePicture") as! PFFile)
self.fullnameArray.append(object.valueForKey("firstname") as! String)
self.usernameArr.append(object.valueForKey("username") as! String)
}
}
self.collectionView.reloadData()
print(self.usernameArr)
print(self.lastPicArray)
}
}
}
As you'll see I have added the query.limit = 5 because when I do it seems to get them in some kind of order...And if in that order some users don't have anything in the lastPic column nothing shows...But what I need it to do is find all the users with something in that column and then limit them to 5...At the moment my code is doing all that apart from limiting them to 5!
If anyone knows how do fix this, I really appreciate any help!
I haven't worked with Swift but it is how it will work for you in objective C, you need to incorporate "whereKeyDoesNotExist" in your query and add limit to it. Following is the working code:
PFQuery *query = [PFQuery queryWithClassName:#"_User"];
[query whereKeyDoesNotExist:#"latestImage"];
query.limit = 5;
[query findObjectsInBackgroundWithBlock:^(NSArray * _Nullable objects, NSError * _Nullable error) {
NSLog(#"Got 5 objects");
}];
I have two table Order and Modifiers. Modifier is the pointer class for the Order. Modifiers has a column (name ,price etc). I want to get all the values of Modifiers with order.
Code
PFQuery *queryLocal= [PFQuery queryWithClassName:#"order"];
[queryLocal whereKey:#"order_no" equalTo:orderno];
[queryLocal includeKey:#"modifiers"];
[queryLocal fromLocalDatastore];
[queryLocal findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (block) {
block(objects,nil);
}
}];
Output :
<modifiers: 0x7a15dc30, objectId: ZgikpV86HB, localId: (null)> {
}
It gives me only the objectId. is there any way to get all values
I've looked all over and have found no joy. I was wondering if someone could help me figure out how to retrieve a random object from a class on parse.com using swift in an iOS app. By no means am I asking someone to write my code, because then what would I learn, but I was wondering if someone could maybe provide a generic example that I could adapt to my project and future projects.
Let's say the class is called ParseClass, and I will need to populate three variables with data from the object in parse., A, B, C -- two with strings, one as an array of strings. Let's say there are ... idk ... 50 objects in the parse class, and I need to retrieve them one at a time randomly.
Logically, I get it ... I need to do a count of the objects in the parseclass, then get a random number from that count, and then use that number to retrieve the object somehow (either directly from parse using a skip random query limit 1, or maybe by getting all the objects into an array (whichever is the best/most efficient code). I just don't know how to format/write the code in swift. Any one think they could help me (and many others apparently) with some generic code I could adapt to my specific project??
Here is some generic code ... I can start it -- I got a basic idea of how it should be, I just don't know swift well enough to complete the block.
var A : String!
var B : [String]!
var C : String!
var query : PFQuery = PFQuery(className: "ParseClass")
query.findObjectsInBackgroundWithBlock {
(objects : [AnyObject]!, error : NSError!) -> Void in
//now what?
I've seen this in other questions here, but I don't know how to incorporate it.
let randomSkip = arc4random_uniform(count)
query.skip = randomSkip, and query.limit = 1.
Any help on this would be greatly appreciated.
Oh -- just saw this in another thread ... it's basically doing what I need, but in objective C and it looks like with only 2 variables... could someone help me rewrite in swift? Sorry to be so loquacious ... the burden of a novice. I promise as I grow more adept, I will help other novices most sympathetically. :-)
- (void)randomQuestion:(void (^)(NSString *question, NSArray *answers))completion {
PFQuery *countQuery = [PFQuery queryWithClassName:#"ParseClass"];
[countQuery countObjectsInBackgroundWithBlock:^(int count, NSError *error) {
NSInteger randomSkip = arc4random_uniform(count);
PFQuery *query = [PFQuery queryWithClassName:#"ParseClass"];
query.skip = randomSkip;
query.limit = 1;
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
if (objects.count) {
PFObject *ParseClassObject = objects[0];
NSString *A = ParseClassObject[#"A"];
NSArray *B = ParseClassObject[#"B"];
completion(A, B);
} else {
NSLog(#"no error, but no ParseClass objects found");
}
} else {
NSLog(#"there was an error %#", error);
completion(nil, nil);
}
}];
}];
}
ObjectHolder should be objectHolder, or objects because it's a parameter name.
Your count for arc4random_uniform would be objects.count.
Downloading the objects and randomly accessing them locally will be most efficient if you need to display all of them anyway. Multiple downloads isn't great.
You're going to run into size limits eventually as the download row count is limited. Perhaps you could download pages and treat the items in each page as a separate collection to view randomly...
So, you wouldn't be using skip or limit, you would just be accessing elements in the objects array.
Removing the items from the array after you've used them is easiest. Or you can randomly sort the array so you don't need to remove
One way you can do it is to set another key called e.g. questionsNumber and each question will be be in that questionNumbers row. And then query the number from the arc4random_uniform(count) so something like this:
var query = PFQuery(className: "ParseClass")
let randomNumber = arc4random_uniform(count)
var randomNumberCast = Int(randomNumber)
query.whereKey("questionNumber", equalTo: randomNumberCast)
query.getFirstObjectInBackgroundWithBlock { (object: PFObject!, error: NSError!) -> Void in
if error == nil {
let questions = object["questions"] as String //This will equal your question at random.
}
}
I'm using Parse within my app. i'm trying to do a query with a limit of 10 objects ordered by descending order of the createdAt property plus I'm using the nearGeopoint:WithinKilometers function. When i run the query, the receive the oldest objects in the database. when i remove the limit of number of objects to be returned, the query returns the latest objects from the newest to oldest (as expected). does the limit do that? isn't it a bug? here is the code, please let me know if there is anything wrong:
PFQuery *postsQuery = [PFQuery queryWithClassName:#"user_p"];
if (city)
{
[postsQuery whereKey:#"geoPoint" nearGeoPoint:[PFGeoPoint geoPointWithLatitude:[city[#"latitude"] doubleValue] longitude:[city[#"longitude"] doubleValue]] withinKilometers:[[[NSUserDefaults standardUserDefaults] valueForKey:#"distanceCovered"] doubleValue]];
}
[postsQuery orderByDescending:#"createdAt"];
[postsQuery includeKey:#"user_id"];
[postsQuery whereKeyExists:#"user_id"];
[postsQuery setLimit:10];
Is there any way to do a query in Parse to get the most recently added PFObject type?
I know that I can do a query with a greater than criteria, but it would be very useful if there was a function to get the most recent object added when no date is known.
Just add a descending order on createdAt and get the first object:
PFQuery *query = [PFQuery queryWithClassName:#"YourClassName"];
[query orderByDescending:#"createdAt"];
[query getFirstObjectInBackgroundWithBlock:^(PFObject *object, NSError *error) {
// code
}];
In Swift:
var query = PFQuery(className: "YourClassName")
query.orderByDescending("createdAt")
query.getFirstObjectInBackgroundWithBlock {(object: PFObject?, error: NSError?) -> Void in
// code
}
This may not address the use case in question. I often want to get back the objectId of the object i just added in code. While it might be automatically possible, i have missed any info in this regard. So i usually have my own unique identifier that i add, and then retrieve the object by that identifier in the async block.. thus getting the objectId..