Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does AlamofireObjectMapper / ObjectMapper support struct type mapping

I am using AlamofireObjectMapper to parse json response to my object. The AlamofireObjectMapper is a extension of ObjectMapper.

According to their documents, my model class has to conform to Mappable protocol. For example:

class Forecast: Mappable {
    var day: String?
    var temperature: Int?
    var conditions: String?

    required init?(_ map: Map){

    }

    func mapping(map: Map) {
        day <- map["day"]
        temperature <- map["temperature"]
        conditions <- map["conditions"]
    }
}

In order to conform to Mappable protocl, my model class has to implement the required initializer and the mapping function for each field. It makes sense.

BUT, how does it support struct type? For example, I have a Coordinate structure, I try to conform to the Mappable protocol:

struct Coordinate: Mappable {
    var xPos: Int
    var yPos: Int

    // ERROR: 'required' initializer in non-class type
    required init?(_ map: Map) {}

    func mapping(map: Map) {
        xPos <- map["xPos"]
        yPos <- map["yPos"]
    }
}

I cannot make my Coordinate conform to the Mappable, because of the error I show above.

(I think it is quite often that using struct for coordinate data instead of using class)

My questions:

Q1. Does AlamofireObjectMapper or ObjectMapper library support struct type? How to use them parsing json response to a struct type object then?

Q2. If those libraries doesn't support parsing json response to struct type object. What is the way to do so in iOS with Swift2 ?

like image 394
Leem.fin Avatar asked May 13 '16 08:05

Leem.fin


1 Answers

BaseMappable protocol is defined like this so you should declare each method to conform Mappable.

/// BaseMappable should not be implemented directly. Mappable or StaticMappable should be used instead
public protocol BaseMappable {
    /// This function is where all variable mappings should occur. It is executed by Mapper during the mapping (serialization and deserialization) process.
    mutating func mapping(map: Map)
}

Mappable protocol is defined like this

public protocol Mappable: BaseMappable {
    /// This function can be used to validate JSON prior to mapping. Return nil to cancel mapping at this point
    init?(map: Map)
}

You have to implement it accordingly:

struct Coordinate: Mappable {
    var xPos: Int?
    var yPos: Int?
    
    init?(_ map: Map) {
    }

    mutating func mapping(map: Map) {
        xPos <- map["xPos"]
        yPos <- map["yPos"]
    }
}

or

struct Coordinate: Mappable {
    var xPos: Int
    var yPos: Int
    
    init?(_ map: Map) {
    }

    mutating func mapping(map: Map) {
        xPos <- map["xPos"] ?? 0
        yPos <- map["yPos"] ?? 0
    }
}

Constructor cannot be marked as required because struct cannot be inherited. mapping function has to be mark as mutating because mutates stored data in structure...

like image 114
JMI Avatar answered Sep 21 '22 00:09

JMI