ObjectMapper + 领域 + Alamofire

ObjectMapper + Realm + Alamofire

我使用 ObjectMapper 映射我的对象,这些对象由 Alamofire 提供并将它们保存在 Realm 中。

一切正常。但是如何删除存在于 Realm 中但已在我的网络服务中删除的对象?

更新:根据下面的答案,我目前以这段代码结束:

 if let overviewItemsArray = response.result.value{

                    do{
                        try self.realm.write{
                            self.realm.delete(self.realm.objects(OverviewItem))
                            self.realm.add(overviewItemsArray, update: true)
                        }
                    }
                    catch let err as NSError {
                        logger.error("Error with realm: \(err.localizedDescription)")
                    }
                    overviewItemsAsList.removeAll()
                    overviewItemsAsList.appendContentsOf(self.realm.objects(OverviewItem)
                        .sorted("sortOrder", ascending: true))
                    successHandler(overviewItemsAsList)
                }

也许有人进一步输入了如何改进它。我有 10 个这种类型的对象。但是在其他对象上我得到了 1500 个项目。

你可以:

-使用 updated_at 字段并通过 id 更新该字段,之后删除所有未更新的对象或

-删除所有对象,然后插入新对象(昂贵,我不会做这样的事情)

我认为你应该选择第一个选项,尤其是当你有大量数据时,当你从网络服务获得响应时,遍历每个并使用 NSDate() 更新数据库中的相应记录,然后删除"old" 个对象。请注意,这不是来自服务器的 updated_at,而是您的本地存储。

如果您的数据量较小,并且您确定它会快速且便宜,那么另一个很好。

这听起来像是您需要实施某种机制来确定在服务器上删除了哪些对象,并明确将该信息中继到您的本地设备以反映该更改。我可以想到一些可能的解决方案:

  • 如果您可以控制 API,您可以实现一个系统,在该系统中,您的设备会告诉服务器上次调用 API 的时间戳,而服务器然后可以 return 其响应中针对在那之后删除的条目的 ID 号列表。

  • 如果您只是每次都下载相同的列表,而不是每次都将 Realm 文件中的所有内容都删除,请手动循环遍历 Realm 文件中的每个条目,看看它是否有下载列表中的相应条目。如果没有,请将其删除。当然,这仍然是一个相对较慢的操作,但它比每次 deleting/recreating 一切都快得多。

  • 因为这听起来像是 Realm 被用来缓存服务器信息,所以你可以在 Realm 对象上设置一个非常严格的到期时间,如果超过则删除它们,或者如果超过则延长对象从服务器刷新。

希望对您有所帮助!

我终于弄明白了,而且效果很好。我计算缓存数据和新数据的差异并将其删除:

private func deleteOrphans(existingData: List<VotingHeader>, fetchedData:[VotingHeader]){

        guard existingData.count>0 else {
            return
        }

        let existingIDs = Set(existingData.map({[=10=].votingID}))
        let incomingIDs = fetchedData.map({[=10=].votingID})
        let idsToDelete = existingIDs.subtract(incomingIDs)

        if idsToDelete.count>0{
            let itemsToDelete =  self.realm.objects(VotingHeader).filter("votingID IN %@",idsToDelete)

            try! self.realm.write{
                self.realm.delete(itemsToDelete)
            }
        }
    }