Esta clase de abajo
class User: NSManagedObject {
@NSManaged var id: Int
@NSManaged var name: String
}
Necesita ser convertida a
{
"id" : 98,
"name" : "Jon Doe"
}
He intentado pasar manualmente el objeto a una función que establece las variables en un diccionario y devuelve el diccionario. Pero me gustaría una mejor manera de lograr esto.
ACTUALIZACIÓN: El protocolo Codable
introducido en Swift 4 debería ser suficiente para la mayoría de los casos de análisis sintáctico de JSON
. A continuación la respuesta es para las personas que están atrapados en las versiones anteriores de Swift y por razones de legado
NSDictionary
, NSCoding
, Printable
, Hashable
y Equatable
.**Ejemplo
class User: EVObject { # extend EVObject method for the class
var id: Int = 0
var name: String = ""
var friends: [User]? = []
}
# use like below
let json:String = "{\"id\": 24, \"name\": \"Bob Jefferson\", \"friends\": [{\"id\": 29, \"name\": \"Jen Jackson\"}]}"
let user = User(json: json)
**Ejemplo
class User: Mappable { # extend Mappable method for the class
var id: Int?
var name: String?
required init?(_ map: Map) {
}
func mapping(map: Map) { # write mapping code
name <- map["name"]
id <- map["id"]
}
}
# use like below
let json:String = "{\"id\": 24, \"name\": \"Bob Jefferson\", \"friends\": [{\"id\": 29, \"name\": \"Jen Jackson\"}]}"
let user = Mapper<User>().map(json)
He trabajado un poco en una solución más pequeña que doesn't requieren la herencia. Pero no ha sido probado mucho. Es bastante feo atm.
https://github.com/peheje/JsonSerializerSwift
Puedes pasarlo a un playground para probarlo. Por ejemplo, la siguiente estructura de clases:
//Test nonsense data
class Nutrient {
var name = "VitaminD"
var amountUg = 4.2
var intArray = [1, 5, 9]
var stringArray = ["nutrients", "are", "important"]
}
class Fruit {
var name: String = "Apple"
var color: String? = nil
var weight: Double = 2.1
var diameter: Float = 4.3
var radius: Double? = nil
var isDelicious: Bool = true
var isRound: Bool? = nil
var nullString: String? = nil
var date = NSDate()
var optionalIntArray: Array<Int?> = [1, 5, 3, 4, nil, 6]
var doubleArray: Array<Double?> = [nil, 2.2, 3.3, 4.4]
var stringArray: Array<String> = ["one", "two", "three", "four"]
var optionalArray: Array<Int> = [2, 4, 1]
var nutrient = Nutrient()
}
var fruit = Fruit()
var json = JSONSerializer.toJson(fruit)
print(json)
imprime
{"name": "Apple", "color": null, "weight": 2.1, "diameter": 4.3, "radius": null, "isDelicious": true, "isRound": null, "nullString": null, "date": "2015-06-19 22:39:20 +0000", "optionalIntArray": [1, 5, 3, 4, null, 6], "doubleArray": [null, 2.2, 3.3, 4.4], "stringArray": ["one", "two", "three", "four"], "optionalArray": [2, 4, 1], "nutrient": {"name": "VitaminD", "amountUg": 4.2, "intArray": [1, 5, 9], "stringArray": ["nutrients", "are", "important"]}}
No estoy seguro de si lib/framework existe, pero si quieres hacerlo automáticamente y quieres evitar el trabajo manual :-) quédate con MirrorType
...
class U {
var id: Int
var name: String
init(id: Int, name: String) {
self.id = id
self.name = name
}
}
extension U {
func JSONDictionary() -> Dictionary<String, Any> {
var dict = Dictionary<String, Any>()
let mirror = reflect(self)
var i: Int
for i = 0 ; i < mirror.count ; i++ {
let (childName, childMirror) = mirror[i]
// Just an example how to check type
if childMirror.valueType is String.Type {
dict[childName] = childMirror.value
} else if childMirror.valueType is Int.Type {
// Convert to NSNumber for example
dict[childName] = childMirror.value
}
}
return dict
}
}
Tómelo como un ejemplo aproximado, carece de soporte de conversión adecuada, carece de recursividad, ... It's sólo MirrorType
demostración ...
P.D. Aquí está hecho en U
, pero vas a mejorar NSManagedObject
y entonces podrás convertir todas las subclases de NSManagedObject
. No es necesario implementar esto en todas las subclases/objetos gestionados.