parse.com'转推'模式过于冗长

时间:2016-01-06 09:40:35

标签: ios swift design-patterns parse-platform

因此,我的任务是使用Parse在应用程序( iOS,Swift )中实现'转推'式功能。

这已在here之前被问过,但这是a)相当高级别的b)我得到了手头的任务 - 我不一定在建筑决策上寻求帮助,不过如果我看来我我显然缺少一些东西,我很乐意接受反馈。

我的应用程序有CAUSES,每个CAUS由USER创建。 还有一个带有TO和FROM用户的FOLLOW表。 首先,我只是查询CAUSES表,其中发布的USER应该与FOLLOW表中TO用户的objectId(当前用户是FROM用户)匹配。更简洁:

let getFollowedUsersQuery = PFQuery(className: Constants.kParseClassFollowers)
getFollowedUsersQuery.whereKey(Constants.kParseFieldFromUser, equalTo: PFUser.currentUser()!)

let causesQuery = PFQuery(className: Constants.kParseClassCauses)
causesQuery.whereKey(Constants.kParseFieldFromUser, matchesKey: Constants.kParseFieldToUser, inQuery: getFollowedUsersQuery)
causesQuery.findObjectsInBackgroundWithBlock({ (objects, error) -> Void in
    if let causes = objects {
        for cause in causes {
          // populate the tableview cells, etc.
        }
    }
})

现在我已经了解了我所遵循的用户的所有原因......这些都非常标准。

这里变得棘手。
每个CAUSE也有一个名为SUPPORTERS的Relation。 现在我需要构建一种方法来从我不遵循的人那里获得所有CAUSES,但是在他们的支持者列表中有我关注的用户。

我还没有找到一个优雅的解决方案,虽然我正在接近一个“蛮力”的解决方案,而且我的程序员大脑中更好的一半是screaming at me like Susan Powter ...

以下是一个示例:

let retweetQuery = PFQuery(className: Constants.kParseClassCauses)
retweetQuery.orderByDescending(Constants.kParseFieldCreatedAt)
retweetQuery.whereKey(Constants.kParseFieldFromUser, notEqualTo: PFUser.currentUser()!)
retweetQuery.whereKey(Constants.kParseFieldFromUser, doesNotMatchKey: Constants.kParseFieldToUser, inQuery: getFollowedUsersQuery)
retweetQuery.findObjectsInBackgroundWithBlock({ (objects, error) -> Void in
    if let causes = objects {
        for cause in causes {
            let supporterRelations = cause.relationForKey(Constants.kParseClassSupporters)
            let supporterQuery = supporterRelations.query()
            supporterQuery.findObjectsInBackgroundWithBlock { (supporters, error) in
                if(error == nil && supporters?.count > 0) {
                    for supporter in supporters! {
                        let user:PFUser = supporter as! PFUser
                        getFollowedUsersQuery.whereKey(Constants.kParseFieldToUser, equalTo: user)
                        getFollowedUsersQuery.whereKey(Constants.kParseFieldFromUser, equalTo: PFUser.currentUser()!)
                        getFollowedUsersQuery.findObjectsInBackgroundWithBlock({ (results, error) -> Void in
                            if(error == nil && results?.count > 0) {
                                for result in results! {
                                    // do stuff
                                }
                            }
                        })
                    }
                }
            }
        }
    }
})

现在,这是纯粹的疯狂,并且非常浪费(特别是考虑到Parse如何计算免费等级 - 我觉得如果推迟到生产阶段,这可能会对我的API限制造成很大影响)。

已完成两个查询,我完全重做一个,然后在SUPPORTER Relations上为每个原因执行另一个查询,然后在该关系中对每个用户执行另一个查询看看我是否遵循它们......一旦我掌握了这些信息,我就需要遍历用户支持的原因(由于Parse查询的异步返回,我觉得我不能回到父级完全循环)...我还没有实现,因为我要放弃 - 必须有更好的方法!

我希望我在这里错过了一个策略......

1 个答案:

答案 0 :(得分:1)

@ jesses.co.tt我很抱歉,如果这太晚太晚了,我肯定会注意到我被问到这几个月之后才会回答,但我认为这一点值得回答(和也许对你来说仍然有价值)。

一般情况下,我100%同意使用Parse进行三重查询是a)按照它的计费方式(在旧系统中)和b)计算方式的效率非常低,看起来像是错误的甚至采用自托管Parse的方法(由于Parse现在已关闭,因此在上下文中这是唯一可用的机制,但我认为当问题被问到时......仍然可能已经上升......无论如何......)。假设可以对一般模式/体系结构进行这些更改,我认为可以以相当干净的方式解决这个问题。

<强> 1) 第一种解决方案是重新模式化数据集,基本上是&#34;外键&#34;每个User的支持者子集都在User表中。这样,您理论上可以做Cause - &gt; {{1},而不是从Supporter - &gt; User - &gt; Cause开始(来自用户,默认情况下你会得到他们的支持者,因为它是一个列)。要在 User 中执行此操作,如果我没记错,您可以将列设置为具有特定类型的数组作为其值,然后使用Parse那里的链接(在Parse仪表板中很好地显示)是实际的object表对象,但在Supporter表中保留了该列的链接。

虽然在 User 方面需要更多工作,但由于您必须手动执行此操作(通过手动我的意思是为了做到这一点,你应该自动编码,但它在开发方面不会免费发生)。通过稍微提前的 write 操作,您可以使用2步 write 而不是3步。

2)如果查询速度有问题,第二种解决方案是为这种数据使用不同的提供程序。在我的几个项目中,我使用基于套接字的方法进行此类数据查询查找,并认为像 Pusher Firebase (两者都非常不同) &strong;&#34;全包性&#34;, Firebase 更像是Parse,但这次来自 Google {{3} } 有点基础和#34; DIY&#34;)。

例如,使用 Pusher ,以及此数据集的套接字+ read表本身具有Cause的缓存的模式s属于它们(并且其中User具有其User s的缓存),这3步查找可以实际上是具有2个参数的1个查询(这是我认为理想的情况)。我相信这也可以通过Parse实现,但是需要对第一个提出的解决方案进行另一个模式重构步骤。

我认为在评论中建议采用类似于此的方法(以上解决方案),但采用的方式更为简洁。我希望这有助于原始提问者或某人。理论上,这也可以像推荐的人一样,使用 Firebase 作为提及的1条评论,但它可以轻松地将此架构构建到托管在其上的 PostgreSQL 数据库中AWS或 PubNub 并在没有开销的情况下完成与Parse完全相同的机制。

此外,由于这是对Parse的引用,Parse现在仅作为开源自托管解决方案提供,因此这里有一个指南,用于迁移到在AWS上自己托管Parse:{{3} }