ObjectMapper:在地图函数

时间:2018-05-15 06:42:46

标签: ios swift reflection objectmapper

我正在使用ObjectMapper一段时间,我发现使用文档中描述的方式为具有大量属性的类编写map函数很麻烦:

func mapping(map: Map) {
    username    <- map["username"]
    age         <- map["age"]
    weight      <- map["weight"]
    array       <- map["array"]
    dictionary  <- map["dictionary"]
    bestFriend  <- map["bestFriend"]
    friends     <- map["friends"]
}

我想知道是否可以使用反射来编写地图函数,如下所示假设我的JSON数据和我的类具有完全相同的属性名称:

func mapping(map: Map) {
    let names = Mirror(reflecting: self).children.flatMap { $0.label }
    for name in names {
        self.value(forKey: name) <- map[name]
    }
}

更新

根据Sweeper的回答,我更新了我的代码:

func mapping(map: Map) {
    for child in Mirror(reflecting: self).children.compactMap({$0}) {
        child <- map[child.label]
    }
}

我想这应该可行。

更新2:

感谢Sweeper,我发现我最初的猜测是错误的,Child只是一个类型的错误:

public typealias Child = (label: String?, value: Any)

所以我的第二次尝试也没有成功。

1 个答案:

答案 0 :(得分:1)

<-运算符声明如下:

public func <- <T: RawRepresentable>(left: inout T, right: Map) {
    left <- (right, EnumTransform())
}

如您所见,左参数声明为inout。这意味着您必须在那里使用可变变量,而不是某些方法的返回值。

所以你需要写下所有的属性。

我找到了这个为您生成映射的插件:https://github.com/liyanhuadev/ObjectMapper-Plugin

在Swift 4中,引入了Codable,但它会自动为您解决问题:

struct Foo: Codable {
    var username: String
    var age: Int
    var weight: Double

    // everything is done for you already! You don't need to write anything else
}