如何在Realm.create中将JSON属性正确映射到模型属性 [英] How to properly map JSON properties to model properties in Realm.create

查看:140
本文介绍了如何在Realm.create中将JSON属性正确映射到模型属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

在许多JSON对象中,有一个名为description的密钥.由于我无法使用具有public dynamic var description属性的Realm对象子类,因此我需要选择另一个名称,并确保在调用realm.create时正确映射了该名称.我知道您在想什么,我可以在调用create之前进行映射.但是,JSON也可能具有嵌套对象/对象数组,当Realm已经知道那些对象映射到何处时,对我来说,为所有嵌套属性设置映射似乎也是多余的.如果我可以简单地在每个Object子类中定义一个映射,然后Realm可以找出其余的映射,那将更加干净.

我解决此问题的第一个尝试是覆盖Objectinit函数(即使注释明确声明不可以,必须尝试),但这种方法不起作用,因为没有采用JSON的init方法.对象实际上是使用realm.create调用的.

有什么方法可以使我的生活更轻松吗?

注意:我正在使用Swift 2.0和Realm的swift-2.0分支

解决方案

使用Swift时,Realm仍不支持正确的映射,因此让我详细说明jpsim注释.

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

以下是我为虚拟项目编写的示例:

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 Mappable协议的mapping函数,又有一个mappedColor函数,它仅仅是映射JSON来检索我的模型对象的便捷方式./p>

然后我可以像这样在网络服务调用响应中使用它:

[...]
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)
    }
}
[...]

I'm currently implementing an insert-or-update pattern with Realm by calling realm.create(T.self, value: object, update: true). object is JSON returned from a rest call and it may contain some or all of the properties associated with that realm object. (In other words, I need to support partial updates.)

In many of the JSON objects there is a key called description. Since I cannot have a Realm object subclass with a property called public dynamic var description I need to choose another name and make sure it is mapped properly when calling realm.create. I know what you are thinking, I can just do the mapping before calling create. However, the JSON may also have nested objects / array of objects and it seems redundant for me to setup mappings for all nested properties as well, when Realm already knows where those objects map to. It would be much cleaner if I could simply define a mapping in each Object subclass and then Realm could figure out the rest.

My first attempt at solving this was to override the init functions for Object (even though comments explicitly say not to, had to try) and that did not work because none of the init methods that take in a JSON object were actually called with using realm.create.

Is there any way to make my life easier here?

Note: I am using Swift 2.0 and the swift-2.0 branch of Realm

解决方案

Realm still doesn't support proper mapping when using Swift, so let me elaborate on jpsim comment.

ObjectMapper provides a powerful mapping mechanism which not only let you choose your model properties names, but also handle nicely any sanitization you might need during the mapping process.

Here is an example I've written for a 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"]
    }
}

You can see I have both a mapping function linked to the ObjectMapper Mappable protocol, as well as a mappedColor function which is nothing more than a convenient way to map a JSON to retrieve my model object.

I can then use it within a webservice call response likeso :

[...]
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)
    }
}
[...]

这篇关于如何在Realm.create中将JSON属性正确映射到模型属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆