user3147770
user3147770

Reputation: 203

How to count objects in parse.com class to get total number from which to pull a random number?

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

Answers (1)

danh
danh

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

Related Questions