How to count rows in a Parse class programmatically in an iOS app using swift?
Quick Answer
findObjectsInBackgroundWithBlock
is constrained by the query limitation to return up to 100 objects by default. This limit can be increased, but only to a maximum of 1000. Because of this, you cannot rely on findObjects
and then counting the results.
Parse has included in the documentation a simple way to count the total number of objects for a class or particular query.
var query = PFQuery(className:"GameScore")
query.whereKey("playerName", equalTo:"Sean Plott")
query.countObjectsInBackgroundWithBlock {
(count: Int32, error: NSError?) -> Void in
if error == nil {
print("Sean has played \(count) games")
}
}
Swift 3
let query = PFQuery(className:"GameScore")
query.whereKey("playerName", equalTo:"Sean Plott")
query.countObjectsInBackground { (count, error) in
if error == nil {
print("Sean has played \(count) games")
}
}
Detailed Explanation
It should also be noted that due to how costly count operations are, Parse has placed limitations on them
Count queries are rate limited to a maximum of 160 requests
per minute. They can also return inaccurate results for classes with
more than 1,000 objects. Thus, it is preferable to architect your
application to avoid this sort of count operation (by using counters,
for example.)
This inaccuracy is not due to the 1000 request object limit. The count query will try to get the total number of records regardless of size, but since the operation may take a large amount of time to complete, it is possible that the database has changed during that window and the count value that is returned may no longer be valid.
The recommended way to handle counts is to essentially maintain your own index using before/after save triggers in cloud code. However, this is also a non-ideal solution because save hooks can arbitrarily fail part way through and (worse) postSave hooks have no error propagation. To add on to this, here is another quote by Hector Ramos from the Parse Developers Google Group.
Count queries have always been expensive once you throw some
constraints in. If you only care about the total size of the
collection, you can run a count query without any constraints and that
one should be pretty fast, as getting the total number of records is a
different problem than counting how many of these match an arbitrary
list of constraints. This is just the reality of working with database
systems.
And lastly, to quote the Parse Engineering Blog Post: Building Scalable Apps on Parse.
Suppose you are building a product catalog. You might want to display
the count of products in each category on the top-level navigation
screen. If you run a count query for each of these UI elements, they
will not run efficiently on large data sets because MongoDB does not
use counting B-trees. Instead, we recommend that you use a separate
Parse Object to keep track of counts for each category. Whenever a
product gets added or deleted, you can increment or decrement the
counts in an afterSave or afterDelete Cloud Code handler.
Count number of objects in Parse.com array]
Try using this:
let query = PFQuery(className: "myClass")
query.findObjectsInBackgroundWithBlock { (results, error) -> Void in
if results != nil {
//Set whatever you want to results.count
}
}
}
I also recommend watching a tutorial on the basics of Parse as this would help you very much. Hope this helps!
How to get all Created Class Names in Parse using swift?
It isn't available via the iOS SDK.
You can get it via the REST interface if you use the master key to fetch the app schema: https://api.parse.com/1/schemas
It may be easier for you to just add a Classes
class with rows for each of the classes, which you manage manually and can simply query with PFQuery
...
How to add another column to my class in Parse.com? (Swift)
Parse allows you to add columns to a class lazily, meaning that you can add a field to your PFObject and if it is not present in your Parse class, Parse will add that column for you.
Here's how you would add a column via code:
// Prepare image
let imageData = UIImagePNGRepresentation(yourImage)
let imageFile = PFFile(name:"image.png", data:imageData) // "image.png" is the name which would be shown on Parse.com
// Add the new field to your object
yourObject["image"] = imageFile
yourObject.saveInBackground()
You'll notice that Parse will create a new column named image
on their web portal.
Create a row programatically Parse Swift
Worked it out myself, here is the code if others were wondering:
var gameScore = PFObject(className:"GameScore")
gameScore["score"] = 1337
gameScore["playerName"] = "Sean Plott"
gameScore["cheatMode"] = false
gameScore.saveInBackgroundWithBlock {
(success: Bool, error: NSError?) -> Void in
if (success) {
// The object has been saved.
} else {
// There was a problem, check error.description
}
}
An example from: https://www.parse.com/docs/ios/guide#objects-saving/iOS
iOS How to fetch next row parse Swift
Ok so with parse you probably dont want to keep calling the server every single time so what you want to do is get your data append it to and array and then just get the information at each index. There are a lot of ways to do this but I'm going to show a simple way to do this. The more you get into parse you can use PFSubclassing and that is a better way to handle your data but for now just do it like this. Create this as a new class
Class QuestionManager{
var question: String?
var answerA: String?
var answerB: String?
var answerC: String?
var answerD: String?
}
In the first class do this.
var questions = [QuestionManager]()
var arrayIndex = 0
let query = PFQuery(className: "test")
query.findObjectsInBackground{ (objects, error) in
if error == nil && objects != nil {
for object in objects as? [PFObject]{
self.questions.append(QuestionManager(
question: object!["question"] as! String,
answerA: object!["answer1"] as! String,
answerB: object!["answer2"] as! String,
answerC: object!["answer3"] as! String,
answerD: object!["answer4"] as! String
))
}
} else {
print("Error")
}
Then two access it just have the index of the array change
self.label.text = questions[arrayIndex].question
Each time you add one to the array it will return the next set of questions and answers
If you need clarification let me know
How to delete rows of table in data browser of Parse(Parse.com) programatically in objective c from xcode
I am using deleteInBackground property to delete record from Parse Table.
eg.
deleteObjectId is defined Parse object.
[deleteObjectId deleteInBackground];
Related Topics
Notify Watchkit App of an Update Without the Watch App Requesting It
iOS Tesseract Ocr Image Preperation
Obscure a Uitextfield Password
How to Scroll to the Exact End of the Uitableview
Xcode 8, iOS 10 - "Starting Webfilter Logging for Process"
Using Enum as Property of Realm Model
Icon Already Includes Gloss Effects
How to Open Location Services Screen from Setting Screen
Cannot Install Cocoapods - No Podfile Found in the Project Directory
How to Load Custom Cell ( Xib) in Uicollectionview Cell Using Swift
iOS 9 - "Attempt to Delete and Reload the Same Index Path"
Xcode 7 Uitests with Localized Ui
Xcode Won't Let to Build for Device After Denying Codesign to Access Keychain
iOS - Uiimagewritetosavedphotosalbum
Uiimagepickercontroller Camera View Rotating Strangely on iOS 8 (Pictures)
How to Convert Including Timezone Date in Swift