Reputation: 203
I am getting an error when I try to count the objects my parse.com class. I need to count the total number of objects so I can then get a random number and use that to query one object. I have a column in my data table called Qnum that numbers each object. Here is my function:
func CallData() {
var query = PFQuery(className: "QuestionsandAnswers")
let randomNumber = arc4random_uniform(count)
var randomNumberCast = Int(randomNumber)
query.whereKey("Qnum", equalTo: randomNumberCast)
query.getFirstObjectInBackgroundWithBlock { (object: PFObject!, error: NSError!) -> Void in
if (error == nil) {
self.Question = object ["Question"] as String!
self.Answers = object ["Answers"] as Array!
self.Answer = object ["Answer"] as String!
if (self.Answers.count > 0) {
self.QuestionLabel.text = self.Question
self.Button1.setTitle(self.Answers[0], forState: UIControlState.Normal)
self.Button2.setTitle(self.Answers[1], forState: UIControlState.Normal)
self.Button3.setTitle(self.Answers[2], forState: UIControlState.Normal)
self.Button4.setTitle(self.Answers[3], forState: UIControlState.Normal)
}
} else {
NSLog("Something is wrong, dude. Sorry.")
}
}
}
My error comes in on the second line in the function "let randomNumber = arc4random_uniform(count)" I've tried (objects.count) to no avail; however when I just plug in the total number of objects, it works, (20) but I'd like to avoid hard coding that number in case I need to add more objects to my class. Any suggestions for this novice?
Solution: danh provided the answer below, but since I had to change just a few things, and I couldn't figure out how to post the revised code in the comments, I'm editing this answered question to now include the solution. This is the code that worked:
func CallData() {
var countQuery = PFQuery(className: "QuestionsandAnswers")
countQuery.countObjectsInBackgroundWithBlock { (count: Int32, error: NSError!) -> Void in
if (error == nil) {
let randomNumber = Int(arc4random_uniform(UInt32(count)))
var query = PFQuery(className: "QuestionsandAnswers")
query.skip = randomNumber
query.limit = 1
query.findObjectsInBackgroundWithBlock { (objects: [AnyObject]!, error: NSError!) -> Void in
if (error == nil) {
var object: AnyObject = objects[0]
self.Question = object ["Question"] as String!
self.Answers = object ["Answers"] as Array!
self.Answer = object ["Answer"] as String!
if (self.Answers.count > 0) {
self.QuestionLabel.text = self.Question
self.Button1.setTitle(self.Answers[0], forState: UIControlState.Normal)
self.Button2.setTitle(self.Answers[1], forState: UIControlState.Normal)
self.Button3.setTitle(self.Answers[2], forState: UIControlState.Normal)
self.Button4.setTitle(self.Answers[3], forState: UIControlState.Normal)
}
} else {
NSLog("Something is wrong with the find request, dude. Sorry. %@", error)
}
}
} else {
NSLog("Something is wrong with the count request, dude. Sorry. %@", error)
}
}
}
Upvotes: 1
Views: 3364
Reputation: 62676
The count cannot be used until it is known, and knowing requires a count api call. Once you have the count, you can use it to bound a random number.
The random can be used to find based on the "Qnum" field, or used as a skip on an unqualified query. Skip is a little less prone to error since it depends only on the count.
Not speaking swift, I did my best to piece together a swift form of this advice. The following will probably be a little bit wrong syntactically, but I'm pretty sure its right in the basic idea...
var countQuery = PFQuery(className: "QuestionsandAnswers")
countQuery.countObjectsInBackgroundWithBlock { (count: Int, error: NSError!) -> Void in
if (error == nil) {
let randomNumber = Int(arc4random_uniform(UInt32(count)))
var query = PFQuery(className: "QuestionsandAnswers")
query.skip = randomNumber
query.limit = 1
query.findObjectsInBackgroundWithBlock { (objects: [AnyObject]!, error: NSError!) -> Void in
if (error == nil) {
var object: AnyObject = objects[0]
self.Question = object ["Question"] as String!
self.Answers = object ["Answers"] as Array!
self.Answer = object ["Answer"] as String!
if (self.Answers.count > 0) {
self.QuestionLabel.text = self.Question
self.Button1.setTitle(self.Answers[0], forState: UIControlState.Normal)
self.Button2.setTitle(self.Answers[1], forState: UIControlState.Normal)
self.Button3.setTitle(self.Answers[2], forState: UIControlState.Normal)
self.Button4.setTitle(self.Answers[3], forState: UIControlState.Normal)
}
} else {
NSLog("Something is wrong with the find request, dude. Sorry. %@", error)
}
}
} else {
NSLog("Something is wrong with the count request, dude. Sorry. %@", error)
}
}
Upvotes: 1