简体   繁体   English

领域和解析集成:如何保存领域

[英]Realm and Parse integration: how to save the realm

I'm trying to create a bundle realm for my application. 我正在尝试为我的应用程序创建一个捆绑软件领域。 I thought it should be quite simple. 我认为应该很简单。 Since I already have all needed records in Parse, I just have to: 由于我已经在Parse中拥有所有需要的记录,因此我只需要:

  • create realm models and objects 创建领域模型和对象
  • load parse records to realm objects 将解析记录加载到领域对象
  • save the realm 保存领域

So, I created two realm models: 因此,我创建了两个领域模型:

class RealmContainer : Object {
    dynamic var rContainerId: String! //should be equal objectId from Parse
    dynamic var rContainerName: String! //should be equal "name" field from Parse
  ...
    var messages = List<RealmMessage>()

    override static func primaryKey() -> String? {
        return "rContainerId"
    }
}

and

class RealmMessage : Object {
    dynamic var rMessageId: String!
    ...
    dynamic var rParentContainer: RealmContainer!
}

Getting results from Parse seems to be working. 从Parse获取结果似乎是可行的。 Also my realm objects are also good 而且我的境界对象也不错

    var allUserContainers: [RealmContainer] = [] 

I was able to populate this array with values from Parse. 我能够用Parse中的值填充此数组。 But when I'm trying to save this realm, I'm getting a) nothing or b) error message 但是,当我尝试保存此领域时,我得到的是a)无或b)错误消息

My code (this one'll get nothing): 我的代码(这个一无所获):

let realm = try! Realm()
try! realm.write {
    realm.add(self.allUserContainers[0])
    print(Realm().path)
    print(realm.path)
    }

My code (this one'll get nothing too): 我的代码(这个也不会得到):

let realm = try! Realm()
try! realm.write {
    realm.create(RealmContainer.self, value: self.allUserContainers[0], update: true)
    print(Realm().path)
    print(realm.path)
    }

My code 3 (this will get me an error message " Terminating app due to uncaught exception 'RLMException', reason: 'Illegal recursive call of +[RLMSchema sharedSchema]. Note: Properties of Swift Object classes must not be prepopulated with queried results from a Realm "): 我的代码3(这将使我收到一条错误消息“ Terminating app due to uncaught exception 'RLMException', reason: 'Illegal recursive call of +[RLMSchema sharedSchema]. Note: Properties of Swift Object classes must not be prepopulated with queried results from a Realm “):

//from firstViewController, realm is a global variable
let realm = try! Realm()

//another swift module
    try! realm.write {
        realm.create(RealmContainer.self, value: self.allUserContainers[0], update: true)
        print(Realm().path)
        print(realm.path)
        }

Obviously I don't properly understand how it should work, but I tried several swift/realm tutorials and they were actually straightforward. 显然,我不太了解它应该如何工作,但是我尝试了一些swift / realm教程,它们实际上很简单。 So, what did I do wrong? 那么,我做错了什么?

Update 更新

So, I updated my code to make it as much simple/readable as possible. 因此,我更新了代码,使其尽可能简单/易读。 I have a Dog class, and I am trying to get Dogs from Parse and put them to Realm. 我有一个Dog课程,我正在尝试从Parse获取Dogs并将它们放到Realm。

AppDelegate.swift AppDelegate.swift

let realm = try! Realm() //global

Dog.swift Dog.swift

class Dog : Object {
    dynamic var name = ""
    dynamic var age = 0
}

User.swift (getDogs and putDogs functions) User.swift(getDogs和putDogs函数)

class User {
    var newDogs:[Dog] = []
...

func getDogs() {
    self.newDogs = []

    let dogsQuery = PFQuery(className: "Dogs")
    dogsQuery.limit = 100
    dogsQuery.findObjectsInBackgroundWithBlock { (currentModes, error) -> Void in
        if error == nil {

            let tempModes:[PFObject] = currentModes as [PFObject]!

            for var i = 0; i < tempModes.count; i++ {
                let temp = Dog()
                temp.name = currentModes![i]["dogName"] as! String
                self.newDogs.append(temp)

            }

        } else {
            print("something happened")
        }
        }
}

...

func putDogs() {

    print(self.newDogs.count)
    try! realm.write({ () -> Void in
        for var i = 0; i < newDogs.count; i++ {
            realm.add(newDogs[i])
        }

    })
        try! realm.commitWrite() //doesn't change anything
    }

error message still the same: 错误消息仍然相同:

Terminating app due to uncaught exception 'RLMException', reason: 'Illegal recursive call of +[RLMSchema sharedSchema]. 由于未捕获的异常“ RLMException”而终止应用程序,原因:“ + [RLMSchema sharedSchema]的非法递归调用。 Note: Properties of Swift Object classes must not be prepopulated with queried results from a Realm 注意:不能使用来自领域的查询结果预填充Swift Object类的属性

I believe I just have some global misunderstanding about how Realm is working because it is extremely simple configuration. 我相信我对Realm的工作方式有一些全局性的误解,因为它的配置非常简单。

About your RealmSwift code : You have implemented it right. 关于您的RealmSwift代码:您已正确实现了它。

When you declare a class of realm in swift, it's a subclass of Object class. 快速声明一个领域类时,它是Object类的子类。 Similarly for the parse it's subclass of PFObject . 同样,对于解析,它是PFObject的子类。

You custom class have to have only one base class. 您的自定义类必须只有一个基类。 So can't use functionalities of both the libraries Parse as well as Realm. 因此,不能同时使用库Parse和Realm的功能。

If you have to have use both Parse and Realm, you need to declare two different classes like RealmMessage and ParseMessage . 如果必须同时使用Parse和Realm,则you need to declare two different classes like RealmMessage and ParseMessage

Retrieve data for ParseMessage from parse and copy properties to RealmMessage. 从解析和复制属性到RealmMessage检索ParseMessage的数据。

Why you want to use both Parse and Realm ? 为什么要同时使用Parse和Realm? parse also provides local data store by just writing Parse.enableLocalDatastore() in appDelegate before 通过仅在Parse.enableLocalDatastore()编写Parse.enableLocalDatastore()之前, parse还可提供本地数据存储

Parse.setApplicationId("key",
            clientKey: "key")

Your Realm Swift code seems fine. 您的Realm Swift代码看起来不错。 Realm is very flexible when creating objects using (_:value:update:) , in being able to take in any type of object that supports subscripts. 使用(_:value:update:)创建对象时,Realm非常灵活,因为它可以接受支持下标的任何类型的对象。 So you could even directly insert PFObject if the schemas matched. 因此,如果架构匹配,您甚至可以直接插入PFObject

The problem seems to be how you're populating the allUserContainers array. 问题似乎在于您如何填充allUserContainers数组。 As the error says, you cannot fetch a Realm Object from Realm and then try and re-add it that way. 如错误所述,您无法从Realm获取Realm Object ,然后尝试以这种方式重新添加它。 If you're trying to update an object already in Realm, as long as the primary key properties match, you don't need to supply the whole object back again. 如果您试图更新Realm中已经存在的对象,只要主键属性匹配,就不需要再次提供整个对象。

Can you please revisit the logic of how your allUserContainers variable is being populated, and if you can't fix it, post the code into your question? 您能否重温一下如何填充allUserContainers变量的逻辑,如果无法解决该问题,请将代码发布到您的问题中?

Sidenote: You probably don't need to define your Realm properties as implicitly unwrapped as well. 旁注:您可能也不需要将Realm属性定义为隐式展开。 This is the recommended pattern: 这是推荐的模式:

class RealmContainer : Object {
    dynamic var rContainerId = ""
    dynamic var rContainerName = ""
}

Actually I found what was wrong: as i suspected it was a stupid mistake, some property in my class was UIImage type, and Realm just can't work with this type (even if I'm not trying to put objects of this class into realm). 实际上,我发现了问题所在:因为我怀疑这是一个愚蠢的错误,我类中的某些属性是UIImage类型,而Realm不能使用该类型(即使我不打算将此类的对象放入领域)。 So, my bad. 所以,我不好。 I am slightly embarassed by it, but will not delete my question because error messages from Realm were not very understandable in this case 我对此感到有些尴尬,但不会删除我的问题,因为在这种情况下,来自Realm的错误消息不是很容易理解

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM