TheValyreanGroup
TheValyreanGroup

Reputation: 3599

JSON into Model extension

I have the following class which i'd like to write an extension method for to easily serialize my JSON into.

class Evaluation: Object {
    var name: String?
    var isFinalized: Bool?
    var id: Int?
    var idString: String? {
        get{
            return String(describing:self.id!)
        }
    }

    convenience init(json: JSON?) {
        self.init()
        if let json = json {
            name = json["evaluationDescription"].rawString()
            isFinalized = json["evaluationFinalized"].intValue == 0 ? false : true
            id = json["evaluationID"].intValue
        }
    }

    override static func primaryKey() -> String? {
        return "id"
    }
}

This is the extension i wrote, but i'd like for it to be mutating and more globally usable. So that i can use the same code for all my models.

extension Evaluation {
    func serialize(from json: JSON){
        var temp = [Evaluation]()
        for (_,j): (String,JSON) in json {
            temp.append(Evaluation(json: j))
        }
    }
}

I tried making the method mutating, but got an error

'mutating' is not valid on methods in classes...

In summary, i'd like to use it like so (json is somewhat pseudo code)...

var json = "{'name':'test','isFinalized','0','id':'532'}"

var evaluations = [Evaluations]()
evaluations.serialize(from: json)

Upvotes: 0

Views: 202

Answers (2)

Ios Developer
Ios Developer

Reputation: 1

protocol JSONable { init?(parameter: JSON) }

//MARK:- JSON extension JSON { func to(type: T?) -> Any? { if let baseObj = type as? JSONable.Type { if self.type == .array { var arrObject: [Any] = [] arrObject = self.arrayValue.map { baseObj.init(parameter: $0)! } return arrObject } else { let object = baseObj.init(parameter: self) return object! } } return nil } }

Upvotes: 0

Gustavo Almeida
Gustavo Almeida

Reputation: 195

Swift 4 has a new protocol called Codable. If you want your class be serializable you just need to make this protocol be adopted by your class. Like this:

class Evaluation: Object, Codable {
    var name: String?
    var isFinalized: Bool?
    var id: Int?
    var idString: String? {
        get{
            return String(describing:self.id!)
        }
    }
}

Since all your properties are from Swift Standard Library, your class is ready to be serialized with JSONEncoder type.

let evaluation = Evaluation()
let encoded = try? JSONEncoder().encode(evaluation)

and decoded like this:

let decoded = try? JSONDecoder().decode(Evaluation.self, encoded)

Since this protocol automatically makes your class serializable, you don't need that initializers, so it can be like this:

class Evaluation: Object, Codable {
    var name: String
    var isFinalized: Bool
    var id: Int
    var idString: String {
        get{
            return String(describing:self.id!)
        }
    }
}

Moreover, if your models don't need to be a class, make it a struct. Structs use less computation to be instantiated and is more Value Type Oriented Programming.

For more information about this, please visit Swift Documentation.

Upvotes: 2

Related Questions