通过Swift解析复杂查询

时间:2015-07-29 18:02:29

标签: ios swift parse-platform

我在Parse中创建复杂查询时遇到了一些困难。我想要实现的是搜索_Users类而不返回结果,如果Invites类中已经存在Invite,则显示Pending文本而不是Add Button,如果我自己和用户都已接受邀请,根本不显示它们。

我已经取得了一些成绩,但我不确定我是否能以最有效的方式实现这一目标。例如,我首先查询_User类并查找与搜索项匹配的任何用户,然后循环遍历,如果objectId == currentUser()。objectId,则跳过该记录。然后我在每个记录的循环中运行另一个查询以查看是否有任何待处理的邀请,如果是这样的话,我为Pending设置了一个标志为true但是我已经在后台完成了搜索,因为我有与第一个查询块在第二个之前完成,而我的标志没有先设置。那么我会进行第三次查询以查看该字段是否被接受?或者有没有办法让这一切都成为一个大问题?我的代码在下面进行搜索:

func performSearchForText(text:String,completion:SearchComplete){         state = .Loading

    // Query Parse

    var containsDisplayName = PFQuery(className:"_User")
    containsDisplayName.whereKey("displayName", containsString: text)

    var containsUsername = PFQuery(className: "_User")
    containsUsername.whereKey("username", containsString: text)

    var query = PFQuery.orQueryWithSubqueries([containsUsername, containsDisplayName])
    query.findObjectsInBackgroundWithBlock {
        (results: [AnyObject]?, error: NSError?) -> Void in
        //self.state = .NotSearchedYet
        var success = false

        if error == nil {
            // Found results
            // Set Result state to either Results or NoResults
            if let results = results {
                //println(results)
                if results.count == 0 {
                    self.state = .NoResults
                } else {
                    // Read Results into UserSearchResult Array
                    // Dont show self in results
                    // If user has already accepted a request, dont show
                    // If they have already invited, show Pending instead of button

                    var userSearchResults = [UserSearchResult]()
                    var searchResult = UserSearchResult()

                    for result in results {
                        if result.objectId != PFUser.currentUser()?.objectId {
                            // Query invites table to see if they already are accepted with user
                            // or if a pending invite exists
                            // Set invite or accepted respectively
                            var invitedQuery = PFQuery(className: "Invites")
                            invitedQuery.whereKey("pending", equalTo: true)
                            invitedQuery.whereKey("inviteToUser", equalTo: result.objectId!!)
                            var invitedQueryResults = invitedQuery.findObjects()
                            if invitedQueryResults?.count > 0 {
                                self.pendingInvite = true
                            }

                            searchResult.displayName = result["displayName"] as! String
                            searchResult.emailAddress = result["username"] as! String
                            searchResult.inviteUserID = result.objectId!!
                            searchResult.invited = self.pendingInvite
                            searchResult.accepted = false
                            userSearchResults.append(searchResult)
                        }
                    }

                    if userSearchResults.count > 0 {
                        self.state = .Results(userSearchResults)
                    } else {
                        self.state = .NoResults
                    }

                }
                    success = true
                }

            dispatch_async(dispatch_get_main_queue()) {
                UIApplication.sharedApplication().networkActivityIndicatorVisible = false
                completion(success)
            }
        } else {
            // Error, print it
            println(error)
        }
    }
}

1 个答案:

答案 0 :(得分:0)

除非您的邀请表中有更多内容,否则我建议将其删除并在您的用户表中添加“invitePending”字段。

然后,您可以使用wherekey(“invitePending”,equalTo:true)进一步优化其他查询。

此外,您可以在开始时执行此类操作,这样您就不必在查询完成块中检查currentUser:

containsDisplayName.whereKey("objectId", notEqualTo: PFUser.currentUser()!.objectId!)

但如果没有存储大量其他信息,你肯定不需要邀请表。如果你必须将它保持为一个单独的表,使用指针(1对1)或PFRelation(1对1)可以省去内部查询的麻烦。