1

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)
        }   
    }
}
2
  • Well, as of this morning (April 9, 2015) this solution no longer works. Just installed xcode update and project wouldn't build. Got a lot of the syntax issues fixed, but this line: countQuery.countObjectsInBackgroundWithBlock { (count: Int32, error: NSError!) -> Void in gives the following error: cannot invoke 'countObjectsInBackgroundWithBlock' with an argument list of type '((Int32, error: NSError!) -> Void in' danh, any ideas??? Probably just a syntax thing ... I mean, I thought we were casting well ??? Commented Apr 9, 2015 at 16:41
  • got it figured out: [link] (stackoverflow.com/questions/29544623/…) Commented Apr 10, 2015 at 3:23

1 Answer 1

1

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)
        }   
    } 
Sign up to request clarification or add additional context in comments.

9 Comments

Hey danh, thank you again. :-) I tried this code and I'm getting an error on the second line" 'Int32' is not a subtype of 'int' ... is that one of those syntactical errors you warned about?
Yes. I based that one on the cast in your code. Does the edit help?
Alas, still getting the same error. Doh! Swift has a countObjects() function, same as (NSInteger)countObjects in Objective C, but I haven't been able to incorporate it either. Ah, the life of a novice ... Thank you for all your help. You helped me on my first question here as well. Much obliged.
Thing is, I feel certain it's a simple solution, especially when just plugging in the number of objects works. If the second line is let randomNumber = arc4random_uniform(20) then I get no error. I just need to find a way to programmatically come up with that number 20 ... in case it changes.
Is it just that one line? In the last edit, after reading this: , kylelevin.com/cast-well-or-get-a-swift-kick-in-the I try casting the input and the output.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.