如何使用 ObjectMapper 映射不同类型?
How to map different type using ObjectMapper?
我正在使用 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 后, User
的 userId
其中 name
为 "first"
为空。
如何将 Int/String
映射到 Int
?
你应该提高你的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
如果你的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
}
}
看了ObjectMapper的代码后,我发现了一个更简单的解决问题的方法,就是自定义transform。
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.
}
}
希望对遇到同样问题的人有所帮助。 :)
我正在使用 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 后, User
的 userId
其中 name
为 "first"
为空。
如何将 Int/String
映射到 Int
?
你应该提高你的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
如果你的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
}
}
看了ObjectMapper的代码后,我发现了一个更简单的解决问题的方法,就是自定义transform。
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.
}
}
希望对遇到同样问题的人有所帮助。 :)