【问题标题】:How to map different type using ObjectMapper?如何使用 ObjectMapper 映射不同的类型?
【发布时间】:2017-07-26 15:08:51
【问题描述】:

我正在使用 ObjectMapper 将我的 JSON 映射到 Swift 对象。

我有以下 Swift 对象:

class User: Mappable {

    var name: String?
    var val: Int?

    required init?(map: Map) { }

    func mapping(map: Map) {
        name <- map["name"]
        val  <- map["userId"]
    }
}

我有这个 JSON 结构:

{
   "name": "first",
   "userId": "1" // here is `String` type.
},
{
   "name": "second",
   "userId": 1 // here is `Int` type.
}

映射 JSON 后,UseruserId 其中name"first" 为空。

如何将Int/String 映射到Int

【问题讨论】:

  • 你不能这样做。您必须为 UserId 选择一种数据类型,它将是 Int 或 String。
  • "val" 在哪里? JSON中userId的key是"userId"吧?
  • @AnhTrungPham 哦,这是我的错误。是的,JSON 中 userId 的键是“userId”,我已经修好了。谢谢。
  • @Steven.L 是的,我也更新了我的答案。
  • 当我像这样使用 Mapper().mapArray(JSONString: str) 我想在这个地方使用自定义转换时如何使用自定义转换

标签: json swift objectmapper


【解决方案1】:

看了ObjectMapper的代码,我发现了一个更简单的解决方法,就是自定义变换。

public class IntTransform: TransformType {

    public typealias Object = Int
    public typealias JSON = Any?

    public init() {}

    public func transformFromJSON(_ value: Any?) -> Int? {

        var result: Int?

        guard let json = value else {
            return result
        }

        if json is Int {
            result = (json as! Int)
        }
        if json is String {
            result = Int(json as! String)
        }

        return result
    }

    public func transformToJSON(_ value: Int?) -> Any?? {

        guard let object = value else {
            return nil
        }

        return String(object)
    }
}

然后,对mapping 函数使用自定义转换。

class User: Mappable {

    var name: String?
    var userId: Int?

    required init?(map: Map) { }

    func mapping(map: Map) {
        name   <- map["name"]
        userId <- (map["userId"], IntTransform()) // here use the custom transform.
    }
}

希望它可以帮助其他有同样问题的人。 :)

【讨论】:

  • 哦,太好了。但是,为了更安全,在transformFromJSON(_ value: Any?) -&gt; Int? 函数中,我认为您应该将这一行result = Int(json as! String)! 更改为result = Int(json as! String) ?? 0。这是因为如果value = "ABC123" 你会得到一个致命的运行时错误。
  • 而且,看起来transformFromJSON 函数永远不会返回nil。所以,考虑将User类中的userId变量更新为Int类型而不是Int?或者更新transformFromJSON函数返回nil而不是默认值为0
  • 还有一件事。你应该接受你的答案,这是一个很好的解决方案。
  • @AnhTrungPham 非常感谢您的提示。我已经更新了答案。 :)
【解决方案2】:

如果您的 API 是这样的 - 这是非常糟糕的 API。你可以做的是有两个变量而不是一个:

class User: Mappable {

    var name: String?
    var valInt: Int?
    var valString: String?

    required init?(map: Map) { }

    func mapping(map: Map) {
        name <- map["name"]
        valInt  <- map["val"]
        valString <- map["val"]
    }
}

您甚至可以添加可以让您获得价值的功能,例如:

// bellow func mapping(map: Map){
func getUserId() -> String {
     if(self.valInt != nil) {
         return "\(valInt!)"
     }
     else {
         return valString!
     }
}

或者,使用 if let:

func getUserId() -> String {
     if let userId  = self.valInt {
         return "\(userId)"
     }
     if let userId = valString {
         return userId
     }
     return ""
}

或者使用可选项,以便稍后您可以使用if let userId = object.getUserId()

func getUserId() -> String? {
     if(self.valInt != nil) {
         return String(valInt)
     }
     else {
         return valString
     }
}

【讨论】:

    【解决方案3】:

    您应该改进您的 API。但是,如果您不能这样做,请尝试以下代码:

    class User: Mappable {
    
        var name: String?
        var val: Int?
    
        required init?(map: Map) { }
    
        func mapping(map: Map) {
            name <- map["name"]
    
            // 1: Get the value of JSON and store it in a variable of type Any?
            var userIdData: Any?
            userIdData <- map["userId"]
    
            // 2: Check the value type of the value and convert to Int type
            if userIdData is Int {
                val = (userIdData as! Int) 
            } else if userIdData is String {
                val = Int(userIdData as! String) 
            }
        }
    }
    

    您可以参考这个文档:Type Casting

    【讨论】:

    • 乐于助人! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-18
    • 1970-01-01
    • 2017-09-02
    • 2016-12-31
    • 1970-01-01
    • 1970-01-01
    • 2014-09-23
    相关资源
    最近更新 更多