Red de conocimiento informático - Material del sitio web - Cómo manejar JSON con elegancia en Swift

Cómo manejar JSON con elegancia en Swift

Conversión de datos JSON

Perfect implementa herramientas básicas de codificación y decodificación JSON a través de una serie de extensiones para los tipos de datos integrados de Swift. La decodificación se realiza mediante extensiones implementadas sobre el tipo de cadena Swift.

La biblioteca JSON de Perfect es de código abierto; consulte aquí para descargar e instalar el soporte de Perfect para Swift JSON:

/PerfectlySoft/Perfect/

Tenga en cuenta, mientras Las herramientas JSON de Perfect son poderosas, pero no lo son.

Si necesita utilizar este sistema, primero asegúrese de declarar la función de importación de la biblioteca PerfectLib al comienzo del código fuente:

import PerfectLib

Encode datos en formato JSON

Puedes convertir los siguientes tipos de datos directamente a cadenas JSON:

Cadena de cadena

Int entero

UInt sin signo entero

Número de punto flotante de doble precisión

Bool Tipo booleano

Array Array de cualquier tipo

Diccionario diccionario con cadena como clave

Tipo opcional opcional

Tipo personalizado heredado del objeto JSONConvertibleObject

¿Nota? Para los tipos opcionales, sólo los tipos opcionales que contengan cualquiera de los anteriores son directamente convertibles. Para tipos opcionales con un valor nulo, la cadena JSON de salida será "nula".

Para codificar el tipo de variable anterior, llame a la función jsonEncodedString() del objeto anterior. Esta función es una extensión especial de Perfect. Esta función puede generar la excepción JSONConversionError.notConvertible.

Ejemplo

let scoreArray: [String: Any] = ["1er lugar": 300, "2do lugar": 230.45, "3er lugar": 150]

let encoded = try scoreArray.jsonEncodedString()

El resultado codificado es la siguiente cadena:

{"segundo lugar": 230.45, "primer lugar": 300, " 3er lugar": 150}

Decodificación de datos JSON

Las cadenas que contienen datos en formato JSON se pueden decodificar usando la función jsonDecode(). Si hay un problema con el formato, esta función generará una excepción de error de sintaxis JSONConversionError.syntaxError.

let encoded = "{\"2do lugar\": 230.45, \"1er lugar\": 300, \"3er lugar\": 150}"

let decoded = intente encoded.jsonDecode() as?[String: Any]

Decodificar la cadena anterior generará un diccionario con el siguiente contenido:

["2nd": 230.44999999999999, "1st" Name": 300, "Name 3": 150]

Dado que decodificar una cadena JSON puede producir valores de datos arbitrarios, el método más común es utilizar un objeto JSON (dict) o una matriz para el procesamiento. Deberá convertir usted mismo al tipo esperado según el resultado.

Decodificar los datos para su uso

Dado que el resultado decodificado es siempre un diccionario [String:Any] o una matriz [Any], es necesario convertir los datos contenidos en él al formato tipo esperado, por ejemplo:

var firstPlace = 0

var secondPlace = 0.0

varthirdPlace = 0

let codificado = "{ \"segundoPlace\ ": 230.45, / "firstPlace\": 300, "thirdPlace\": 150}"

guard let decoded = prueba encoded.jsonDecode() as ? String: Any] else {

devuelve

}

para (clave, valor) en {

tecla de cambio {

caso " primer lugar":

primerPlace = valor como! Int

caso "segundo lugar":

segundoPlace = valor como! Doble

caso "tercer lugar":

tercerPlace = valor como!

Predeterminado:

descanso

}

}

print("Top 3:\r" "1er lugar" "(primerlugar)" " puntos\r" "Segundo lugar:" "(segundo nombre)" "puntos\r" "Segundo lugar:". "puntos\r" "3er lugar:" "(tercer lugar)" " puntos " puntos")

El resultado de salida es:

Tres primeros:

Primer lugar: 300 puntos

Segundo lugar: 230,45 puntos

Tercer lugar: 150 puntos

Decodificación de nulos en Datos JSON

Debido a que los valores nulos en JSON no tienen tipo, el sistema los reemplaza con objetos JSONConvertibleNull.

Por ejemplo:

let jsonString = "{\"Primer lugar\": 300, \"Cuarto lugar\": null, \"Segundo lugar\": 230.45, \"Tercer lugar\": 150 } "

si se deja decodificar = prueba jsonString.jsonDecode() como?[String:Cualquiera] {

para (clave, valor) en decodificado {

si deja el valor como?JSONConvertibleNull {

print("Campo\"\(clave)\"es nulo")

}

}

}

El resultado es:

El campo "thour" está vacío

Objeto que se puede convertir a JSON

Perfect's Conversión JSON La biblioteca proporciona funciones de codificación y decodificación para clases personalizadas. Simplemente herede de la clase base JSONConvertibleObject, como se muestra en el siguiente ejemplo:

//Herede un objeto personalizado que se puede convertir al formato JSON de la clase base.

clase pública JSONConvertibleObject:JSONConvertible {

///Constructor predeterminado

public init() {}

/// Obtener JSON clave/valor

public func setJSONValues(_ value: [String: Any]) {}

/// Establece las propiedades del objeto según la clave/valor JSON.

public func getJSONValues() -gt; [String: Any] { return [String: Any]() }

/// Codifica el objeto en texto JSON

función pública jsonEncodedString() lanza -gt; String {

return try self.getJSONValues().jsonEncodedString()

}

}

Cualquier objeto que deba codificarse o decodificarse usando JSON primero debe registrar el objeto en el sistema. El registro debe completarse cuando se inicia la solicitud. Se llamará a la función JSONDecoding.registerJSONDecodable para completar el registro del objeto. La función se define de la siguiente manera:

public class JSONDecoding {

/// Esta función devuelve una nueva instancia de un objeto personalizado basado en los datos del miembro JSON.

alias de tipo público JSONConvertibleObjectCreator = () -gt; JSONConvertibleObject

registro de función pública estáticaJSONDecodable(nombre. Cadena, creador: JSONConvertibleObjectCreator)

}

Los objetos registrados deben tener un nombre exclusivo. También se requiere una función de creador para crear nuevas instancias del objeto cuando sea necesario.

Cuando el sistema codifica un objeto JSONConvertibleObject, llama a la función getJSONValues ​​del objeto. Esta función devuelve un diccionario [Cadena: Cualquiera] que contiene todos los valores de campos y atributos utilizados para codificar el objeto. El diccionario debe contener un campo que declare el tipo de objeto. El valor del campo tipo debe ser el mismo que el nombre registrado al inicio del programa. El campo correspondiente a este valor de propiedad está determinado por la propiedad JSONDecoding.objectIdentifierKey.

Cuando el sistema decodifica dicho objeto, primero busca el valor JSONDecoding.objectIdentifierKey y luego el constructor creador del objeto previamente registrado. Luego, el sistema crea automáticamente un nuevo objeto según el tipo y el constructor, y llama a la función setJSONValues(_ value: [String: Any]) para establecer el valor de cada campo. La función se llama con un diccionario que contiene todos los datos decodificados pasados ​​como argumento. El valor de la propiedad coincidirá con el valor devuelto previamente por la función de codificación getJSONValues. En la función setJSONValues ​​​​, el objeto restaurará todas las propiedades y datos.

El siguiente ejemplo demuestra cómo definir un objeto JSONConvertibleObject personalizado y convertirlo en una cadena JSON. Luego se decodifica y se compara con el objeto original. ¿Aviso? El objeto de este ejemplo extrae el valor de propiedad del campo especificado directamente del diccionario llamando a la función getJSONValue, lo que permite devolver un valor predeterminado si el campo especificado no está contenido en el diccionario.

Este ejemplo se divide en las siguientes partes.

Definición de clase

clase Usuario: JSONConvertibleObject {

static let RegisterName = "usuario"

var firstName = ""

var apellido = ""

var edad = 0

anular la función setJSONValues(_ valores: [Cadena: Cualquiera]) {

self. nombre = getJSONValue(nombre: "primer nombre", de.edad = getJSONValue (nombre: "edad", de: valores, valor predeterminado: 0)

}

anular la función getJSONValues() -gt; [Cadena: Cualquiera] {

return [

JSONDecoding.objectIdentifierKey: User.registerName,

"firstName": firstName,

"apellido": apellido,

"edad": edad

)

}

}

Registre la información de la clase definida

// Ejecute solo una vez

JSONDecoding.registerJSONDecodable(nombre: User.registerName, creador: { return User() })

Codificación de objetos:

let user = User()

user.firstName = "Donnie"

user.lastName = "Darko"

user.age = 17

let encoded = try user.jsonEncodedString()

Los datos codificados son los siguientes:

{"lastName ": "Darko", "age": 17, "_jsonobjid": "user", "firstName": "Donnie" }

Decodificación de objetos:

guard let user2 = intentar codificar. jsonDecode() as?Usuario else {

return // Defectuoso

}

// Verifique si los valores de los atributos son consistentes

XCTAssert(usuario.primerNombre == usuario2.primerNombre)

XCTAssert(usuario.apellido == usuario2.apellido)

XCTAssert(usuario.edad == usuario2.edad)

Error de conversión JSON

Durante el proceso de codificación y decodificación JSON, el sistema puede generar una excepción de conversión JSONConversionError, que se define de la siguiente manera:

//Durante el Proceso de codificación y decodificación JSON Excepciones de errores que pueden ocurrir.

public enum JSONConversionError: ErrorProtocol {

/// El objeto no admite la conversión JSON.

case notConvertible(Any)

/// El campo proporcionado no es una cadena.

case invalidKey(Any)

/// Error de sintaxis en texto JSON.

Error de sintaxis entre mayúsculas y minúsculas

}