J'essaie de convertir ou de convertir un dictionnaire en objet mais je ne sais pas comment le faire.

Voici ma classe:

import Foundation

class DTOStore: NSObject {

    var _Id: Int64?
    var _StoreId:String?
    var _Name:String?
    var _Address:String?

    var Id: Int64 {
        get {
            return _Id!
        }
        set (pValue) {
            _Id = pValue
        }
    }

    var StoreId:String {
        get {
            return _StoreId!
        }
        set (pValue) {
            _StoreId = pValue
        }
    }

    var Name:String {
        get {
            return _Name!
        }
        set (pValue) {
            _Name = pValue
        }
    }

    var Address:String {
        get {
            return _Address!
        }
        set (pValue) {
            _Address = pValue
        }
    }
}

Et je veux faire quelque chose comme ça:

let vDTOStore:DTOStore = SQLiteConnectionManager.selectRowDatabase(vCommand, pNumColumns: 4) as! DTOStore

Où le résultat de SQLiteConnectionManager.selectRowDatabase (vCommand, pNumColumns: 4) est un dictionnaire [String: String], en tenant compte du fait que la fonction sera convertie en tant que beaucoup d'objets différents, c'est pourquoi elle renvoie toujours une [String: String] .

Mais comme vous pouvez le deviner, cela ne fonctionne pas, et je n'ai aucune idée de la façon de le faire.

Merci pour l'aide.

0
Marco Antonio Uzcategui Pescoz 20 avril 2017 à 17:30

3 réponses

Meilleure réponse

Vous ne pouvez pas convertir un dictionnaire en objet personnalisé.
Vous devez le mapper en écrivant un initialiseur approprié.

Votre objet peut être réduit à

class DTOStore: NSObject {

    let id: Int64
    let storeId: String
    var name: String
    var address: String

    init(dictionary: [String:String]) {
        self.name = dictionary["name"] ?? ""
        self.storeId = dictionary["storeId"] ?? ""
        self.address = dictionary["address"] ?? ""
        let idString = dictionary["id"] ?? "0"
        self.id = Int64(idString) ?? 0
    }

    var dictionaryRepresentation : [String:String] {
        return ["name" : name, "storeId" : storeId, "address" : address, "id" : "\(id)"]
    }
}

Si les clés n'existent pas, les valeurs sont définies sur une chaîne vide / 0.
id et storeId sont déclarés comme des constantes (let).


PS: Puisque la source du dictionnaire est une base de données SQL qui retournera toujours tous les champs demandés dans tous les enregistrements et si les champs sont déclarés comme non NULL, vous pouvez même écrire

    init(dictionary: [String:String]) {
        self.name = dictionary["name"]!
        self.storeId = dictionary["storeId"]!
        self.address = dictionary["address"]!
        self.id = Int64(dictionary["id"]!)
    }
4
vadian 20 avril 2017 à 15:02

J'utiliserai un struct (mais si vous préférez un class, remplacez simplement le mot struct par class ).

struct DTOStore {
    let id: Int64
    let storeId:String
    let name:String
    let address:String

    init?(dict: [String:String]) {
        guard
            let idString = dict["id"],
            let id = Int64(idString),
            let storeId = dict["storeId"],
            let name = dict["name"],
            let address = dict["address"]
            else { return nil }


        self.id = id
        self.storeId = storeId
        self.name = name
        self.address = address
    }
}

Initialiseur disponible

Le DTOStore a un initialiseur disponible.

Ceci est utile lorsque vous souhaitez initialiser une instance de votre type personnalisé à l'aide d'un dictionnaire ou d'un JSON (car il n'y a aucune garantie que toutes les clés / valeurs requises seront présentes).

Si l'initialiseur Failable reçoit en entrée un dictionnaire qui ne contient pas toutes les valeurs attendues, alors l'instance non créée et l'initialiseur renvoie nil.

Plus d'informations sur cette approche ici https://developer.apple.com/swift/blog /? id = 37

3
Luca Angeletti 20 avril 2017 à 14:59

Grâce à toutes vos réponses, j'ai fini par faire ceci:

import Foundation

class DTOStore: NSObject {

    var _Id = Int64()
    var _StoreId = Int64()
    var _Name:String = ""
    var _Address:String = ""
    var _DTOStoreArray = [DTOStore]()

    var Id: Int64 {
        get {
            return _Id
        }
        set (pValue) {
            _Id = pValue
        }
    }

    var StoreId:Int64 {
        get {
            return _StoreId
        }
        set (pValue) {
            _StoreId = pValue
        }
    }

    var Name:String {
        get {
            return _Name
        }
        set (pValue) {
            _Name = pValue
        }
    }

    var Address:String {
        get {
            return _Address
        }
        set (pValue) {
            _Address = pValue
        }
    }

    var DTStoreArrar: [DTOStore] {
        get {
            return _DTOStoreArray
        }
    }

    init(pValue: [String:String]) {
        super.init()
        self._Id = Int64(pValue["Id"]!)!
        self._StoreId = Int64(pValue["StoreId"]!)!
        self._Name = String(pValue["Name"]!)!
        self._Address = String(pValue["Address"]!)!
    }

    init(pArray: [[String:String]]) {
        super.init()
        for vValue in pArray {
            self._DTOStoreArray.append(DTOStore(pValue: vValue))
        }
    }
}

Et l'appel est comme ça:

let vDTOStore = DTOStore(pValue: SQLiteConnectionManager.selectRowDatabase(vCommand, pNumColumns: 4))

Codage heureux.

0
Marco Antonio Uzcategui Pescoz 21 avril 2017 à 07:32