【问题标题】:Swift ObjectMapper type inferenceSwift ObjectMapper 类型推断
【发布时间】:2016-05-03 14:12:02
【问题描述】:

亲爱的 Stackoverflowers,

我在使用 ObjectMapper 方面遇到了障碍,所以让我们直奔主题。

我将模型保存为 SQLite 表中的临时记录,格式为 JSON。每个模型都有一个类型字段,用于唯一标识它映射到的模型类型。

例如,如果我们有符合 Animal 协议的模型 Dog、Cat、Mouse,则有一个等效的 AnimalType (DogType, CatType, MouseType) 枚举,它也是每个模型中的一个字段。保存到数据库后,我无法找到一种优雅的方式来将从数据库加载的 JSON 映射到 Model 类的实际实例。

我目前正在做的是通过 NSJSONSerialization 将 JSON 转换为 JSON 字典并在字典中查询类型。一旦找到类型,我就切换所有类型,实例化一个相关的 Mapper 对象并尝试反序列化该对象。我觉得这是一种蛮力方法,并且正在考虑可能有更好的方法来解决这个问题。

结论性

模型:Dog、Cat、Mouse(符合Animal,有AnimalType要求)

枚举:AnimalType(DogType、CatType、MouseType)

问题除了手动检查每个类型并实例化正确的映射器之外,如何确定并正确实例化 Mapper 对象以将加载的 JSON 反序列化为实例。

enum AnimalType {
    case Dog
    case Cat
    case Mouse
}

protocol Animal {
    var animalType: AnimalType { get }
}

struct Dog: Animal {
    var animalType = AnimalType.Dog
}

struct Cat: Animal {
    var animalType = AnimalType.Cat
}

struct Mouse: Animal {
    var animalType = AnimalType.Mouse
}

【问题讨论】:

    标签: ios swift objectmapper


    【解决方案1】:
    import ObjectMapper
    
    enum AnimalType : String {
        case Cat = "Cat"
        case Dog = "Dog"
        case Mouse = "Mouse"
    }
    
    class Animal: StaticMappable, Mappable {
        var animalType: AnimalType?
    
        required init?(_ map: Map) {}
    
        init() {}
    
        func mapping(map: Map) {
            animalType <- (map["animalType"], EnumTransform<AnimalType>())
        }
    
        static func objectForMapping(map: Map) -> BaseMappable? {
            let typeString: String? = map["animalType"].value()
            if let typeString = typeString {
                let animalType: AnimalType? = AnimalType(rawValue: typeString)
                if let animalType = animalType {
                    switch(animalType) {
                        case AnimalType.Cat: return Cat()
                        case AnimalType.Dog: return Dog()
                        case AnimalType.Mouse: return Mouse()
                    }
                }
            }
            return Animal()
        }
    }
    
    class Cat: Animal {
        var purr: String?
    
        required init?(_ map: Map) {
            super.init(map)
        }
    
        override init() {
            super.init()
        }
    
        override func mapping(map: Map) {
            super.mapping(map)
    
            purr <- map["purr"]
        }
    }
    
    class Dog: Animal {
        var bark: String?
        var bite: String?
    
        required init?(_ map: Map) {
            super.init(map)
        }
    
        override init() {
            super.init()
        }
    
        override func mapping(map: Map) {
            super.mapping(map)
    
            bark <- map["bark"]
            bite <- map["bite"]
        }
    }
    
    class Mouse: Animal {
        var squeak: String?
    
        required init?(_ map: Map) {
            super.init(map)
        }
    
        override init() {
            super.init()
        }
    
        override func mapping(map: Map) {
            super.mapping(map)
    
            squeak <- map["squeak"]
        }
    }
    
    class Owner : Mappable {
        var name: String?
        var animal: Animal?
    
        required init?(_ map: Map) {}
    
        func mapping(map: Map) {
            name <- map["name"]
            animal <- map["animal"]
        }
    }
    
    let catJson = "{\"animalType\":\"Cat\",\"purr\":\"rrurrrrrurrr\"}"
    let cat = Mapper<Cat>().map(catJson)
    if let cat = cat {
        let catJSONString = Mapper().toJSONString(cat, prettyPrint: false)
    }
    
    let ownerJson = "{\"name\":\"Blofeld\", \"animal\":{\"animalType\":\"Cat\",\"purr\":\"rrurrrrrurrr\"}}"
    let owner = Mapper<Owner>().map(ownerJson)
    if let owner = owner {
        let ownerJSONString = Mapper().toJSONString(owner, prettyPrint: false)
    }
    

    我写这篇文章是在寻找来自 Jackson 的 @JsonSubTypes 的 Swift 等效项以用于 JSON 子类的多态映射。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-16
      • 2014-08-26
      相关资源
      最近更新 更多