我有一个可编码Swift结构的层次结构,我需要将其存储在云中的MongoDB中(Atlas(。我确实不需要在本地保存这些结构,而且这个应用程序在存储这些数据后就不需要访问这些数据。(还有其他应用程序访问它,但这超出了这个问题的范围。(
MongoDB曾经提供一个名为Stitch的解决方案,它确实让我能够做到这一点:我的iOS应用程序有一个codable
Swift结构,该iOS应用程序连接到MongoDB的Atlas云上的Stitch应用程序,我能够将该结构插入DB中的集合中。
有了Stitch,我可以这样做:
let itemsCollection = mongoServiceClient.db(“myDatabase”).collection(“myCollection”,
withCollectionType: MyStruct.self)
itemsCollection.insertOne(myStruct)
现在Stitch显然被Realm取代了,Realm是MongoDB收购并与Atlas云集成的一个以前的第三方本地持久层。
Realm与Stitch不向后兼容,它似乎不再能够将Swift结构映射到MongoDB后端:它现在可以同步Realm对象,即Realm定义的抽象基类的ObjC桥接子类。将我的应用程序在多个地方使用的几十个结构转换成这样的类太麻烦了,尤其是因为我这样做的唯一目的是将它们上传到后端,因为我不需要Realm的任何核心功能(毫无疑问是出色的(。
(顺便说一句,我发现从结构到对象的迁移,尤其是在Objective-C基础上的迁移,非常令人困惑,因为它非常违背潮流:很明显,Swift和值类型是苹果平台的未来…(
我的问题:有没有一种方法我可能错过了,那就是连接到Atlas上的Realm应用程序,并将定义为Swift structs的文档插入Atlas DB中的集合?
或者有没有一种相当简单的方法可以将JSON转换为Realm对象?根据我所读到的内容,我仍然需要为对象定义一个模式,由于我的源结构包含几个嵌入的结构,因此需要为每个结构创建Object
子类,这是我真正需要避免的。基本上,我是围绕MongoDB和Stitch设计应用程序的这一功能的,我还没有准备好突然适应Realm的限制而不增加价值。
最后,如果所有这些都失败了,有没有办法将我的structs编码为某种官方MongoDB API(例如Realm(可以用于插入的格式?
我已经可以将结构编码为JSON,但这似乎还不够。我看过关于MongoDB Realm Remote Access的文档,但除了连接到DB之外,它没有说明我的用例。
我收到的错误消息表明我需要创建一个Document
(也称为Dictionary<String, Optional<AnyBSON>>
(,其中AnyBSON
是一个定义BSON值类型的枚举。我还没有找到任何关于将任何内容转换为该格式的文档:是否有API,或者我是否需要将结构或JSON分解为AnyBSON
值的层次结构?
在回答这个问题之前,我会说这不是一个具体的答案,而是关于如何完成问题中所要求的内容的更多指导。
首先,让我重新陈述问题
在不存储的情况下将数据插入MongoDB Realm的过程是什么本地或使用Realm对象;请改用类、结构(或其他(。
为了说明,我们在MongoDB Realm(Atlas(中存储了一些任务,而本地没有存储任何任务。在这里,我将创建一个包含任务信息的文档并插入它
我们首先需要定义数据将存储在哪里以及将其存储在哪个集合中:
let app = Your App
let client = app.currentUser!.mongoClient("mongodb-atlas")
let database = client.database(named: "task-database")
let collection = database.collection(withName: "TaskClass")
然后我们将创建一些BSON来将文本数据存储在中
let _id = AnyBSON(ObjectId.generate())
let taskName = AnyBSON(stringLiteral: "Inserted Task")
let status = AnyBSON(stringLiteral: "Open")
let partition = AnyBSON(stringLiteral: Constants.REALM_PARTITION_VALUE)
然后,对于每个BSON,给每个BSON一个密钥:值对(字典(
let idDict = ("_id", _id)
let taskDict = ("name", taskName )
let statusDict = ("status", status)
let partitionDict = ("_partitionKey", partition)'
最后,我们将创建并编写一个文档到MongoDB Realm
let myTaskDoc = Document(dictionaryLiteral: idDict, taskDict, statusDict, partitionDict)
collection.insertOne(myTaskDoc, { result in
print(result)
})
以上代码回答了问题
MongoDB Realm Swift API是否仍然可以将结构插入到图集收藏,像Stitch?
是的!事实上,我完全没有使用Struct。请记住,上面的代码实际上是为了简单起见——显然,利用Structs
或Classes
将为您的数据提供更多的灵活性和封装。这将通过手工制作或更新现有的类或结构来实现,这样在编写数据时,可以使用函数以AnyBSON格式设置属性并返回Document。
class TaskClass {
var name = ""
func toBson() -> Document {
let taskName = AnyBSON(stringLiteral: self.name)
let taskDict = ("name", taskName )
let myTaskDoc = Document(dictionaryLiteral: taskDict) //abbreviated
return myTaskDoc
}
然后使用
let doc = myTask.toBson()
collection.insertOne(doc, { result in
print(result)
})
使用Codable和JSONEncoder((可以很容易地将JSON数据直接存储在结构中,然后将BSON数据发送到服务器