A continuación encontrarás traducido al castellano el artículo escrito por Gabriel Ludosanu y publicado originalmente en el Blog oficial de Xojo.
JSONItem es una clase nativa para trabajar con JSON. En función de como la utilices tratará tus datos como si fuese un diccionario estándar (pares de clave-valor) o bien como un array basado en índice cero.
Parte 1: Crear el JSON
Crear JSON desde cero implica instanciar un nuevo JSONItem y añadir datos sobre este. No crees JSON mediante la concatenación de cadenas, dado que tiende a “fallar” con facilidad, y tendrás que andar liado con caracteres de escape donde proceda… y además JSONItem hace que sea completamente innecesario.
La carga básica
Cuando simplemente necesitas enviar un objeto a un servicio web:
Var apiPayload As New JSONItem
apiPayload.Value("endpoint") = "/users/create"
apiPayload.Value("timestamp") = 1715423000
apiPayload.Value("forceSync") = True
// Obtén el resultado como cadena
Var jsonString As String = apiPayload.ToString
// {"endpoint":"/users/create","timestamp":1715423000,"forceSync":true}
Creando Arrays
Si estás creando una lista de etiquetas o IDs, utiliza el método .Add. Cuando llames a .Add, Xojo tratará la instancia de JSONItem como un array JSON de forma subyacente.
Var tags As New JSONItem
tags.Add("xojo")
tags.Add("desktop")
tags.Add("api")
Var jsonString As String = tags.ToString
// ["xojo","desktop","api"]
Anidaciones
La mayoría de las API requieren del uso de cargas de datos anidados. Puedes mapear este tipo de estructura mediante el uso de varios objetos JSONItem y asociarlos luego entre sí.
Var payload As New JSONItem
payload.Value("status") = "active"
Var user As New JSONItem
user.Value("id") = 982
user.Value("username") = "johndoe"
Var roles As New JSONItem
roles.Add("admin")
roles.Add("editor")
user.Value("roles") = roles // Asocia el array al objeto user
payload.Value("data") = user // Asocia el objeto user a la carga principal
Var jsonString As String = payload.ToString
// {"status":"active","data":{"id":982,"username":"johndoe","roles":["admin","editor"]}}
Parte 2: Parsear (interpretar) JSON
Cuando se trata de interpretar un JSON recibido, puedes pasar la cadena JSON recibida directamente en el Constructor de una nueva instancia JSONItem.
Leer la respuesta
Cuando un servidor devuelve una simple configuración o bien un token de autenticación puedes simplemente extraer los valores deseados.
Var rawJSON As String = "{""token"":""abc123xyz"",""expiresIn"":3600,""active"":true}"
Var response As New JSONItem(rawJSON)
Var token As String = response.Value("token")
Var expiresIn As Integer = response.Value("expiresIn")
Var isActive As Boolean = response.Value("active")
Manejar las claves opcionales con Lookup
Si utilizas .Value(“Key”) y la clave en cuestión no se encuentra en el JSON recibido Xojo lanzará una excepción de clave no encontrada (KeyNotFoundException). En vez de escribir el típico código que contemple esta posibilidad y la detecte, como por ejemplo…
If response.HasKey("key") Then
// aquí se encuentra el código que extraería la información
End If
…es preferible utilizar .Lookup(), ya que te permitirá definir un valor por omisión en el caso de que no se encuentre dicha clave definida; y todo en una sola línea de código:
Var rawJSON As String = "{""username"":""johndoe""}"
Var response As New JSONItem(rawJSON)
// Devuelve "johndoe" dado que la clave está presente
Var user As String = response.Lookup("username", "anonymous")
// Devuelve False porque "forceSync" no se encuentra en el elemento JSON
Var isSyncForced As Boolean = response.Lookup("forceSync", False)
Recorrer un Array
Si una API te devuelve una lista con registros:
Var rawJSON As String = "[{""id"":1, ""name"":""Alice""}, {""id"":2, ""name"":""Bob""}]"
Var userList As New JSONItem(rawJSON)
For i As Integer = 0 To userList.Count - 1
Var currentUser As JSONItem = userList.ValueAt(i)
Var id As Integer = currentUser.Value("id")
Var name As String = currentUser.Value("name")
System.DebugLog(id.ToString + ": " + name)
Next
Profundizar con los Nodos anidados
Aquí es donde .Child() entra en juego. Mientras que .Value() devuelve una Variante genérica (que no puedes asociar directamente), el método .Child(“Key”) devuelve de forma explícita el objeto anidado como instancia JSONItem. Esto permite realizar una asociación sin dificultad.
Var rawJSON As String = "{""weather"":{""current"":{""temp"":22, ""condition"":""Sunny""}}}"
Var forecast As New JSONItem(rawJSON)
// Usa .Child() para obtener objetos, mientras que .Value() extraerá los datos primitivos finales
Var temperature As Double = forecast.Child("weather").Child("current").Value("temp")
Var condition As String = forecast.Child("weather").Child("current").Value("condition")
Part 3: Identificar la estructura
Las API son notablemente inconsistentes. Chequea la propiedad .IsArray para conocer el tipo de estructura con la que debes de trabajar antes de parsearla, de modo que cuando la recorras no se produzca un error.
Var rawJSON As String = "[""apple"", ""banana"", ""orange""]"
Var parsedData As New JSONItem(rawJSON)
If parsedData.IsArray Then
System.DebugLog("Looks like an array with " + parsedData.Count.ToString + " items.")
For i As Integer = 0 To parsedData.Count - 1
System.DebugLog(parsedData.ValueAt(i).StringValue)
Next
Else
System.DebugLog("It's a standard dictionary.")
If parsedData.HasKey("data") Then
System.DebugLog(parsedData.Value("data").StringValue)
End If
End If
¡Y eso es todo! Para obtener más información sobre JSONItem, recuerda consultar la documentación en línea disponible desde este enlace.