如何使用swift在iOS应用程序中以编程方式计算Parse类中的行?

我有一个parsing后端为我的iOS应用程序。 我有一个称为“测验”的parsing类。 如何读取Parse类中的行数,我必须在iOS应用程序中使用它?

我正在使用下面的代码,但xcode不input代码块。

var cnt = 1 var query = PFQuery(className:"quiz") query.findObjectsInBackgroundWithBlock { (objects: [PFObject]?, error: NSError?) -> Void in if error == nil { // The find succeeded. print("Successfully retrieved \(objects!.count) scores.") cnt = objects!.count } else { // Log details of the failure print("Error: \(error!) \(error!.userInfo)") } } return cnt 

谢谢!

快速回答

findObjectsInBackgroundWithBlock受限于查询限制,默认返回多达100个对象 。 这个限制可以增加,但最多只能达到1000 。 正因为如此,你不能依赖findObjects然后计算结果。

Parse在文档中包含了一个简单的方法来计算一个类或特定查询的对象总数。

 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") } } 

详细说明

还应该注意的是,由于计数操作成本高昂,Parse对它们进行了限制

计数查询的速率限制为每分钟最多160个请求。 对于超过1,000个对象的类,它们也可能返回不准确的结果。 因此,build议您的应用程序避免这种计数操作(例如,使用计数器)。

这种不准确性不是由于1000请求对象的限制。 计数查询会尝试获取logging总数,而不考虑大小,但由于操作可能需要大量时间才能完成,因此可能在该窗口期间数据库已更改,并且返回的计数值可能不是更有效。

处理计数的推荐方法是在云代码中使用保存触发器之前/之后基本维护自己的索引。 然而,这也是一个非理想的解决scheme,因为save hooks可以任意部分通过,并且(更糟糕)postSave hooks没有错误传播。 为了补充这一点,这里是Parse Developers Google Group的 Hector Ramos的另一个引用。

如果你只关心集合的总大小,你可以运行一个没有任何约束的计数查询,而且应该是非常快的,因为获取logging的总数是与计算其中有多less个与任意约束列表相匹配的问题不同。 这只是使用数据库系统的现实。

最后,引用parsing工程博客文章: 构build可扩展的应用程序parsing 。

假设您正在构build产品目录。 您可能想要在顶级导航屏幕上显示每个类别中的产品数量。 如果您为这些UI元素中的每一个运行查询计数,则它们将无法在大型数据集上高效运行,因为MongoDB不使用计数B树。 相反,我们build议您使用单独的Parse对象来跟踪每个类别的计数。 无论何时添加或删除产品,您都可以在afterSave或afterDelete Cloud代码处理程序中增加或减less计数。

由于计数是asynchronous检索的,返回计数的方法是在完成闭包内而不是使用return cnt

这里是一个例子:

 func countObjectsWithCompletion(completion: (Int?)->(Void)) { var query = PFQuery(className:"quiz") query.findObjectsInBackgroundWithBlock { (objects: [PFObject]?, error: NSError?) -> Void in if error == nil { // The find succeeded. print("Successfully retrieved \(objects!.count) scores.") completion(objects!.count) } else { // Log details of the failure print("Error: \(error!) \(error!.userInfo)") completion(nil) } } } countObjectsWithCompletion { (myObjectCount: Int?) in if let cnt = myObjectCount { print("count is \(cnt)") } else { print("error getting count") } }