1

I'm building a rating app in Swift where I'm storing an image's average votes, total votes, and current vote in Parse. I want to update the row without having the objectId.

Giving each image an objectId + querying Parse for every time that image gets voted on seems a bit too much considering I have about 1000 images.

var userData = PFObject(className:"UserData")

    userData.setObject(0, forKey: "imageNumber")
    userData.setObject(0, forKey: "totalVotes")
    userData.setObject(0, forKey: "Average")


    userData.saveInBackground()

For every time the user taps to vote on an Image (1-10) by tapping on an IBAction I want to update Parse by incrementing 1) the total # of votes, 2) the new average from this newest vote and 3) i want to update the user interface to show this.

For now, this is what I have attempted with no luck. This is buggy and doesn't work, and I'm basing it off of other questions posted as well as from the Parse docs.

This is what I have for now:

 @IBAction func one(sender: UIButton) {
   //This is "one" vote. There are 9 more IBActions that do the exact same thing

   //Here is where I would update the labels on the UI
   // I would also have a function that is triggered to update parse based on this increment to the total # of votes and the average. 
   // This would also update the UI based on the votes received, querying the data from Parse. 
}

    func updateParse() {
        var randNumber = Int32()

        counter = 0
        counter++

    var query = PFQuery(className:"UserData")
        query.countObjectsInBackgroundWithBlock  {
            (count: Int, error: NSError!) -> Void in
            if error == nil {
                randNumber = arc4random_uniform(count)
                query2.whereKey("ImageNumber", equalTo:randNumber)
                query2.getFirstObjectInBackgroundWithBlock {
                    (userData: PFObject!, error: NSError!) -> Void in

                    if error != nil {
                       println(error)
                    } else {
                        let votes = userData["totalVotes"] as Int

                    }
                }
            }

}
    }

I'm attempting to find a number that matches the image number so that based on what image the user is on, when the user taps the vote, the IBaction will trigger the function that will look for which objectID the image matches with Parse.

I'm having trouble querying Parse so that it updates the image that it's on, because I don't know how to update JUST the row.

Any ideas? Thank you so much...

PS,

To make things a little more clear thanks to feedback from questions:

I don't need 100000 objectIds. I just need to update the respective row for when the user is on the specific image.

For example: if a user is on image783 and votes on the image and gives that image a "7" as a rating , I want to add "7" to that row in "totalVotes" of image783 on parse so that this image now has an additional vote of 7 added to the average/total, ultimately effecting the total average of that image and the total votes that the image received (i would calculate the average in the Xcode file). The total # of votes and the average votes from ALL users would ultimately be shown on the UI by being queried from Parse.

Lukesivi
  • 2,206
  • 4
  • 25
  • 43
  • Given that each object in Parse already has an objectID I don't understand why you aren't just using that. – Paulw11 Feb 21 '15 at 00:30
  • If I have to do that for 1,000 images, 1000 times, it's going to eat all my memory up... Unfortunately that's the only way I can think of for now... – Lukesivi Feb 21 '15 at 00:32
  • Are you using a tableview? Can you show the entire class? – ericgu Feb 21 '15 at 00:33
  • It's not a table view. It's a hot or not tinder style app where you vote on one image, and then click next go to the next image. – Lukesivi Feb 21 '15 at 00:33
  • Why do you need 1000000 object ids? I am not understanding your problem. – Paulw11 Feb 21 '15 at 00:38
  • I don't need 100000 objectIds. I just need to update each row when the user is on the specific image. For example: if a user is on image783 and votes on the image and gives that image a "7" as a rating , I want to add "7" to that row of image783 on parse that this image now has an additional vote of 7, ultimately effecting the total average of that image and the total votes that the image received. The total # of votes and the average votes from ALL users would ultimately be shown on the UI by being queried from Parse. – Lukesivi Feb 21 '15 at 00:43
  • If you don't need to record the individual votes, just the effect of the vote, then I would create a Parse CloudCode function `vote` that takes an objectID and returns the updated object. The function merely needs to add 1 to the vote count and increment the total of votes. – Paulw11 Feb 21 '15 at 00:47
  • You could also create a cloud code function to return the random image because continually calling `countObjectsInBackground` is expensive and unnecessary – Paulw11 Feb 21 '15 at 00:50
  • In the docs for CoreCloud it actually gives an example similar to what I'm building: https://www.parse.com/docs/cloud_code_guide under Cloud Functions about the Movie Rating site example. Thanks a lot. But this is only in Javascript. Would I have to add a new file in Xcode to implement the JS code? Or can this be done in swift? – Lukesivi Feb 21 '15 at 00:59
  • The Cloud Code javascript is executed on the Parse server – Paulw11 Feb 21 '15 at 01:01
  • Cloud code will not work if you truly have 100k objects. There is a limit of 1000 objects. – ericgu Feb 21 '15 at 01:48
  • @ericgu They are only dealing with one object at a time - the object that is being voted on. It doesn't matter how many items there are that can be voted on. – Paulw11 Feb 21 '15 at 08:49
  • @Paulw11 thought they wanted to calculate agg stats like averages – ericgu Feb 21 '15 at 11:18
  • @ericgu you can calculate a running average using a cumulative total and a number of samples. There is no need to keep the individual samples – Paulw11 Feb 21 '15 at 11:23
  • @Paulw11 https://parse.com/questions/how-to-calculate-the-sum-of-a-column – ericgu Feb 21 '15 at 11:27
  • Yeah, no need for the objectID. But how do I connect the image the user is on to the objectID/row in Parse? I don't understand how I can even do this for the Cloud-Code... – Lukesivi Feb 21 '15 at 11:29
  • Why wouldn't you have the objectID for the image that the user is looking at? Surely the PFObject for the image was retrieved from Parse? – Paulw11 Feb 21 '15 at 11:30
  • @ericgu you don't need to sum a column, because you don't have the individual votes. You have an 'Image' PFObject with columns `cumulativeTotal` and `numberOfVotes`. When a person votes, say, 6, add 6 to the `cumulativeTotal` and 1 to the `numberOfVotes`. The average at any point in time is `cumulativeTotal/numberOfVotes` – Paulw11 Feb 21 '15 at 11:34
  • @Paulw11 yes but cumulative running totals would be calculated how? I assume its serverside. Those have limits. – ericgu Feb 21 '15 at 11:45
  • Yes, server side. The vote function only needs to update a single row at a time. – Paulw11 Feb 21 '15 at 11:47
  • For now, since I am only testing off of Xcode and just starting to build the server side on Parse I don't have the image files in Parse. Adding the images to Parse is a good idea... But even if I do add the image files to a new class in Parse, called "Images", how would I create a function in Xcode to know exactly what file/row in the other class "UserData" to update? Wouldn't i have to create a function that looks for all 1,000 images? – Lukesivi Feb 21 '15 at 12:10
  • Even if the image itself doesn't exist on Parse you are going to have to create a row in Parse for each image in your dataset, as you need a consistent object id across all app instances. You can just store the image name in Parse and then use `imagedNamed` to retrieve it from the local bundle to start with. I don't know why you would want to update `userData` - this isn't about users it is about images - unless the user is the image. I suspect that I don't know enough about your data to give you a precise answer, but you will need an objectID - searching won't scale – Paulw11 Feb 21 '15 at 12:19
  • Yes, exactly it's not about the user. The user just votes on the images, giving the image new values. To put it simply: it's a hot or not app. Whoever is on the app, rates other people/restaurants/clubs, etc. on a scale of 1-10. As mentioned, overtime they vote, the average and total votes gets updated for that specific image. Question: I would need to create a matching objectID for for the image which is in class "Images" and I should give the same objectID for the stats that correspond with the image in another class called "ImageData"? – Lukesivi Feb 21 '15 at 12:22
  • right, so you need one row in Parse for every 'thing' that you can vote on. Each object/row in Parse has an objectID, so presumably your app has retrieved this object/row in order to show the details to the user. The user votes - you update the row with a total vote count, and cumulative total of vote scores - the average can then be calculated as I said before. – Paulw11 Feb 21 '15 at 12:28
  • I see. And the imageFile should be added to the same Class in that case under the same ObjectID? (Instead of having 2 classes) – Lukesivi Feb 21 '15 at 12:29
  • And should I set the my code in Xcode to iterate over an array of all the objectIDs through a counter? So that when the user hits "next" the image changes as it's being pulled from Parse, and when the user hits an Inaction i set an updateMethod function to update the data in Parse as well as the UI. Right? – Lukesivi Feb 21 '15 at 12:33
  • I wouldn't iterate - I would create a Cloud Code function that returns a random object - it is more efficient on network traffic. – Paulw11 Feb 21 '15 at 12:34
  • Having the images in a separate class with a relationship would be an advantage if you wanted multiple images per thing – Paulw11 Feb 21 '15 at 12:35
  • Yes, there would only be 1 image to vote on. So if I create a Cloud Code function that stores the images and returns a random image to the user, which Parse method would help identify which objectID it needs to update? – Lukesivi Feb 21 '15 at 12:38
  • Don't think about objectids - the cloud code function would return a PFObject - You can just update that PFObject. Internally the Parse framework will use the IDs (and you can retrieve it if you want to) but you don't have to worry about it. – Paulw11 Feb 21 '15 at 12:48
  • Thank you so much. I'll send an update to this post once I've given this a few tries. Thanks again! – Lukesivi Feb 21 '15 at 13:18

0 Answers0