ObjectMapper 基本使用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ObjectMapper 基本使用相关的知识,希望对你有一定的参考价值。

参考技术A 基本使用

使用时,类或结构体必须遵循Mappable协议

class User: Mappable 

    var username: String?

    var age: Int?

    var weight: Double!

    var array: [Any]?

    var dictionary: [String : Any] = [:]

    var bestFriend: User?                       // Nested User object

    var friends: [User]?                        // Array of Users

    var birthday: Date?

    required init?(map: Map) 

    

    // Mappable

    func mapping(map: Map) 

        username    <- map["username"]

        age         <- map["age"]

        weight      <- map["weight"]

        array       <- map["arr"]

        dictionary  <- map["dict"]

        bestFriend  <- map["best_friend"]

        friends     <- map["friends"]

        birthday    <- (map["birthday"], DateTransform())

    

struct Temperature: Mappable 

    var celsius: Double?

    var fahrenheit: Double?

    init?(map: Map) 

    

    mutating func mapping(map: Map) 

        celsius     <- map["celsius"]

        fahrenheit  <- map["fahrenheit"]

        //反向转换

        fahrenheit >>> map["重新命名JSON中的字段"]

    

对JSON进行互换

let user = User(JSONString: JSONString)let JSONString = user.toJSONString(prettyPrint: true)

或者这样转换let user = Mapper<User>().map(JSONString: JSONString)let JSONString = Mapper().toJSONString(user, prettyPrint: true)

支持类型

Int

Bool

Double

Float

StringRawRepresentable (Enums)

Array<Any>

Dictionary<String, Any>

Object<T: Mappable>

Array<T: Mappable>

Array<Array<T: Mappable>>

Set<T: Mappable>

Dictionary<String, T: Mappable>

Dictionary<String, Array<T: Mappable>>

Mappable Protocol

mutating func mapping(map: Map)

解析JSON时,此功能在成功创建对象后执行。 当生成JSON时,它是在对象上调用的唯一函数。

init?(map: Map)

ObjectMapper使用这个构造器来创建对象。 在对象序列化之前,开发人员可以使用它来验证JSON。 在函数内返回nil将阻止映射发生。

required init?(map: Map)

    // check if a required "name" property exists within the JSON.

    if map.JSON["name"] == nil 

        return nil

    

嵌套对象的映射

[if !supportLists]· [endif]dictionary嵌套映射

"distance" : 

     "text" : "102 ft",

     "value" : 31

//直接将31 映射到  distanceValuefunc mapping(map: Map) 

    distanceValue <- map["distance.value"]

[if !supportLists]· [endif]Array嵌套映射

//直接获取数组第一个元素的值distance <- map["distances.0.value"]

[if !supportLists]· [endif]key中含有.,禁用嵌套点语法

func mapping(map: Map) 

    identifier <- map["app.identifier", nested: false]

[if !supportLists]· [endif]自定义嵌套类型



  "kr.xoul.user": 

    "kr.xoul.name": "Suyeol Jeon",

    "kr.xoul.username": "devxoul"

  

//这种情况下,mapping解析出来就是不正确的

func mapping(map: Map) 

  // this will parse the key as ["kr"]["xoul"]["user"]["kr"]["xoul"]["name"]

  name <- map["kr.xoul.user.kr.xoul.name"]

//自定义嵌套类型func mapping(map: Map) 

  // this will parse the key as ["kr.xoul.user"]["kr.xoul.name"]

  name <- map["kr.xoul.user->kr.xoul.name", delimiter: "->"]

自定义转换规则

ObjectMapper支持在映射过程中转换值的自定义变换。

class People: Mappable 

   var birthday: NSDate?

   required init?(_ map: Map) 

   

   func mapping(map: Map) 

       birthday <- (map["birthday"], DateTransform())

   

   let JSON = "\"birthday\":1458117795332"

   let result = Mapper<People>().map(JSON)

除了使用ObjectMapper给我们提供的转换规则(DateTransform,DateFormatterTransform,DataTransform,DateTransform,DictionaryTransform)外,我们还可以通过实现TransformType协议来自定义我们的转换规则

public protocol TransformType 

    associatedtype Object

    associatedtype JSON

    func transformFromJSON(_ value: Any?) -> Object?

    func transformToJSON(_ value: Object?) -> JSON?

TransformOf

ObjectMapper为我们提供了一个TransformOf类来实现转换结果,TransformOf实际就是实现了TransformType协议的,TransformOf有两个类型的参数和两个闭包参数,类型表示参与转换的数据的类型

let transform = TransformOf<Int, String>(fromJSON:  (value: String?) -> Int? in 

    return Int(value!), toJSON:  (value: Int?) -> String? in

    if let value = value 

        return String(value)

    

    return nil)

//使用的时候

id <- (map["id"], transform)

也可以直接这样写

id <- (map["id"], TransformOf<Int, String>(fromJSON: Int($0!) , toJSON: $0.map String($0) ))

子类

子类可以继承父类的映射

class Base: Mappable 

    var base: String?

    required init?(map: Map) 

    

    func mapping(map: Map) 

        base <- map["base"]

    

class Subclass: Base 

    var sub: String?

    required init?(map: Map) 

        super.init(map)

    

    override func mapping(map: Map) 

        super.mapping(map)

        sub <- map["sub"]

    

泛型

ObjectMapper同样可以处理泛型类型的参数,不过这个泛型类型需要在实现了Mappable协议的基础上才可以正常使用

class Result<T: Mappable>: Mappable 

    var result: T?

    required init?(map: Map)

    

    func mapping(map: Map) 

        result <- map["result"]

    

let result = Mapper<Result<User>>().map(JSON)

Mapping 上下文

在映射期间传递的Map对象具有可选的MapContext对象,如果在映射期间需要传递信息,该对象可供开发人员使用。只需创建一个实现MapContext的对象(它是一个空协议),并在初始化期间将其传递给Mapper。

struct Context: MapContext 

    var importantMappingInfo = "Info that I need during mapping"

class User: Mappable 

    var name: String?

    required init?(map: Map)

    

    func mapping(map: Map)

        if let context = map.context as? Context 

            // use context to make decisions about mapping

        

    

let context = Context()let user = Mapper<User>(context: context).map(JSONString)

如何使用 ObjectMapper 和 Realm 对象声明字典

【中文标题】如何使用 ObjectMapper 和 Realm 对象声明字典【英文标题】:How can I declare dictionary using both ObjectMapper and Realm object 【发布时间】:2017-01-10 05:54:27 【问题描述】:

我使用 ObjectMapper 进行 JSON 解析,使用 Realm 进行持久性,请帮助我如何声明一个字典,以便它与 Object Mapper 和 Realm 兼容。

 class UserInfo: Object,Mappable

var name:String?
var identifier:String?
var accountType:String?
var devices:[UserDevice]?
required init?(map: Map)




// Mappable
func mapping(map: Map)

    name <- map["username"]
    identifier <- map["identifier"]
    accountType <- map["accountType"]
    devices <- map["devices"]

===========

class UserDevice:Object,Mappable

var deviceName:String?
var deviceType:String?
var deviceIdentifier:String?

required init?(map: Map)




// Mappable
func mapping(map: Map) 
    deviceName <- map["name"]
    deviceType <- map["type"]
    deviceIdentifier <- map["identifier"]




 JSON :


 
username = santhosh;
"identifier" = "IDJSDJSJS";
configstatus = SET;
configtype = DEFAULT;
"data_center" = "evs.idrive.com";
devices = 
    "Ankita\LKKKK" = 
        identifier = LJJDFDD;
        name = "Ankita iPAD";
        type = iPad;
    ;
    "ARUN\LKKKHJH" = 
        identifier = LJJDFDFFD;
        name = "ARUN iPhone";
        type = ipHone;
    ;

    accountStatus = 2;
    acctype = Test;

如何声明用户设备以使其与 Realm 和 ObjectMapper 兼容。

【问题讨论】:

【参考方案1】:

有一个ObjectMapper extension for Realm 允许您处理领域List 属性。

在您上面的代码中,您没有将您的属性定义为 Realm 可以识别的属性。您需要为所有原始类型添​​加 dynamic 前缀,并为数组使用 Realm List 对象。

ObjectMapper 扩展有示例代码来展示如何解析 List 对象,但它应该看起来像这样:

class UserInfo: Object, Mappable

    dynamic var name: String?
    dynamic var identifier: String?
    dynamic var accountType: String?
    let devices = List<UserDevice>()

    func mapping(map: Map) 
        name       <- map["username"]
        identifier <- map["identifier"]
        accountType <- map["accountType"]
        devices    <- (map["devices"], ListTransform<User>())
    


class UserDevice: Object, Mappable

    dynamic var deviceName: String?
    dynamic var deviceType: String?
    dynamic var deviceIdentifier: String?

【讨论】:

感谢“动态”关键字。我正在使用它,但我忘了粘贴该代码。我已经尝试过您的方法,但它不起作用,因为如果我们将设备声明为 let devices = List() 对象映射器无法识别它们,因为它们是以字典数组的形式出现的。 如果我尝试标记动态 var userDevices: List?收到错误“无法将属性标记为动态,因为它的类型无法在 Objective-C 中表示”。 ObjectMapper 理解它在 JSON 中的保存方式。 我应该将设备声明为 let devices = [String:UserDevice] 以便 ObjectMapper 可以理解 JSON,否则 Objectmapper 总是返回 nil 嗯,好的。是的,Realm List 对象不是 Objective-C,所以它们不需要 dynamic 关键字。如果将其更改为[String:UserDevice],它将不会保存在 Realm 中。 嗯,我不能将对象声明为 [String:UserDevice]

以上是关于ObjectMapper 基本使用的主要内容,如果未能解决你的问题,请参考以下文章

JSON处理——FastJsonJacksonGson详细使用

Jackson的JSON处理-ObjectMapper

如何使用 ObjectMapper 和 Realm 对象声明字典

Jackson ObjectMapper类使用解析

ObjectMapper的使用

ObjectMapper使用