如何在Realm.create中

时间:2015-09-03 16:26:39

标签: swift realm

我目前正在通过调用realm.create(T.self, value: object, update: true)与Realm实现插入或更新模式。 object是从休息调用返回的JSON,它可能包含与该领域对象关联的部分或全部属性。 (换句话说,我需要支持部分更新。)

在许多JSON对象中,有一个名为description的密钥。由于我不能拥有一个名为public dynamic var description的属性的Realm对象子类,因此我需要选择另一个名称并确保在调用realm.create时正确映射它。我知道你在想什么,我可以在调用create之前进行映射。但是,JSON也可能有嵌套的对象/对象数组,而且当Realm已经知道这些对象映射到的位置时,为所有嵌套属性设置映射似乎也是多余的。如果我可以简单地在每个Object子类中定义一个映射,然后Realm可以找出其余部分,那将会更加清晰。

我解决这个问题的第一个尝试是覆盖init的{​​{1}}函数(即使注释明确说不要,不得不尝试)并且这不起作用,因为没有一个init方法实际上使用Object调用了一个JSON对象。

有没有办法让我的生活更轻松?

注意:我使用的是Swift 2.0和Realm的realm.create分支

3 个答案:

答案 0 :(得分:2)

Realm在使用Swift时仍然不支持正确的映射,所以让我详细说明jpsim的评论。

ObjectMapper提供了一种强大的映射机制,不仅可以让您选择模型属性名称,还可以很好地处理映射过程中可能需要的任何清理。

以下是我为dummy project撰写的示例:

import ObjectMapper

class Color: RLMObject, Mappable{

    dynamic var myId = 0
    dynamic var myTitle = ""
    dynamic var username = ""
    dynamic var hex = ""

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

    required convenience init?(_ map: Map){
        self.init()
    }

    static func mappedColor(dict:Dictionary<String, AnyObject>) -> Color{
        return Mapper<Color>().map(dict)! as Color
    }

    func mapping(map: Map) {
        id <- map["id"]
        title <- map["title"]
        username <- map["userName"]
        hex <- map["hex"]
    }
}

你可以看到我有一个链接到ObjectMapper mapping协议的Mappable函数,以及一个mappedColor函数,它只不过是将JSON映射到一个方便的方法。检索我的模型对象。

然后我可以在webservice调用响应中使用它:

[...]
if let JSON:Array = response.result.value as? Array<[String: AnyObject]> {

    do{
        try RLMRealm.defaultRealm().transactionWithBlock {
            for dict in JSON{
                let color = Color.mappedColor(dict)
                RLMRealm.defaultRealm().addOrUpdateObject(color)
            }
        }
    } catch let error as NSError {
        print(error)
    }
}
[...]

答案 1 :(得分:1)

您也可以使用SwiftyJSONModel。领域模型看起来像这样:

final class Person: Object {
    dynamic var name = ""
    dynamic var age = ""
    dynamic var isMarried = false
}

extension Person: JSONObjectInitializable {
    enum PropertyKey: String {
        case name, age, isMarried
    }

    convenience init(object: JSONObject<PropertyKey>) throws {
        self.init()
        name = try object.value(for: .name)
        age = try object.value(for: .age)
        isMarried = try object.value(for: .isMarried)
    }
}

这个框架有一些很好的功能,比如:

  1. 密钥全部包含在枚举中,因此您会收到自动填充
  2. 推断出所有类型,无需指定是String还是Int
  3. 如果JSON无效,您将收到详细错误。这确实节省了很多时间
  4. 轻松访问嵌套JSON

答案 2 :(得分:0)

Realm没有任何内置的keypath /值映射机制,因此传递给Object(value:)的任何内容都需要与该模型的模式完全匹配。就像KVC一样。

无论你做什么,在将这些值传递给Realm之前,你都需要清理(例如映射键,转换值,折叠/展开对象)。您可以通过递归遍历从JSON获得的字典/数组,或使用像ObjectMapper这样的库来实现这一目的,该库旨在简化此类工作。 Here's one ObjectMapper&amp;领域用户使用这两种工具的方式。

值得注意的是,Realm确实打算在未来最终支持这种键映射(跟踪为#694),但尚未开始的工作尚未开始。