Compatibile con Xcode 8

Parsing JSON con il linguaggio Swift | Crea la tua app per il Meteo

ENTRA NEL NOSTRO GRUPPO FACEBOOK

Alza la mano se almeno una volta hai sentito parlare del signor JSON!

Che sia un blog, post o domanda su stackoverflow, in qualsiasi angolo del pianeta c’è sempre qualche sviluppatore che parla e cita Mister JSON. Alcuni individuano questa figura misteriosa nel capo del priorato di Sion. Ebbene si! JSON è alla guida di un complotto, una setta misteriosa, che dal 2006 sta cercando di sradicare e distruggere il suo rivale più temibile, XML.

Non preoccuparti se ancora non conosci mister JSON, a fine tutorial anche tu sarai un adepto del priorato.

Torna alla realtà Peppe!

JSON ovviamente non è una persona. É un metodo intuitivo e minimalista che permette di descrivere strutture e gerarchie di dati. Viene utilizzato principalmente per il trasferimento di dati da un web server ad un’applicazione (web o su dispositivo).

JSON è un formato utilizzato per la trasmissione di informazioni via web. Qualcuno dice che tra qualche anno, il JSON, sarà la forma più utilizzata per lo scambio dati tra server e dispositivi mobili/fissi.

leggere-un-file-json-con-il-linguaggio-swift

Ma, torniamo a noi. Il tutorial è diviso in 2 parti.

Nella prima parte, dato che lo reputo necessario, ti spiegherò cos’è un file JSON. Nella seconda si passerà alla realizzazione di un’applicazione che legge ed interpreta i dati contenuti in un file JSON.

Creerai un’applicazione per la lettura delle informazioni del meteo della tua città.

In questa guida/tutorial sto dando per scontato la conoscenza del linguaggio di programmazione Swift e dei principi basilari della programmazione ad oggetti.

Le premesse le ho fatte. Tu sei pronto a vedere come eseguire Parsing JSON con il linguaggio Swift?

Allora cominciamo!

[su_spoiler title=”Indice Paragrafi” style=”fancy”]
  1. Cos’è il formato JSON
    1. Come si rappresentano gli oggetti
    2. Gli array in JSON
    3. I tipi di dati permessi
  2. Le differenze tra JSON e XML
  3. Come leggere e richiedere un file JSON
    1. Creare il JSON con i dati del meteo fornito da OpenWeatherMap
    2. Validare e formattare un file JSON disordinato
    3. I tre passaggi obbligatori per la lettura corretta di un JSON
  4. Creare un’applicazione iOS con Swift per la lettura di un JSON (meteo app con OpenWeatherMap)
  5. HTTP Request e Download file JSON con il linguaggio Swift
    1. Sbloccare le connessioni HTTP non sicure
  6. Deserializzare e verificare il Data scaricato in JSON con Swift
  7. Convertire un JSON in Dizionario o Array del linguaggio Swift
[/su_spoiler]

Cos’è JSON

JSON è l’acronimo di JavaScript Object Notation ovvero il sistema che permette di rappresentare, tramite la notazione JavaScript, gli oggetti.

Un oggetto, inteso secondo i principi della programmazione ad oggetti (che ti invito a leggere), è l’istanza reale di un modello chiamato classe. Per JavaScript, il concetto di classe e oggetto è leggermente diverso rispetto a quello che hai appreso con linguaggi tipo Swift o Objective-C (infatti in JS si definiscono come function), ma la sostanza è praticamente la stessa.

Immagina di voler descrivere il tuo aspetto ad una persona che non conosci.  In genere, quando ti descrivi ad una ragazza/o, escludendo varie forme di imbarazzo, si comincia partendo dal colore degli occhi, capelli, altezza ecc.

Quindi ad ogni attributo che generalmente identifica la persona (occhi, capelli, peso, ecc) assegni il rispettivo valore che ti caratterizza. In pseudo codice potresti scrivere qualcosa del genere:

Rappresentazione di un oggetto tramite JSON

Ecco come io mi rappresenterei se fossi un adepto del JSON:

Forse ho esagerato? Nah, aspetta che ti dica come leggere ciò che ho scritto!

  • Le parentesi graffe servono ad incapsulare un’informazione. Le parentesi graffe più esterne, la prima e l’ultima, racchiudono un oggetto o blocco. Nota come fuori le parentesi non c’è un parametro che identifica il blocco, come accade in Swift dove il nome della classe precede le parentesi, bensì tutte le informazioni sono contenute all’interno.
  • Ogni informazione è espressa nella formula <chiave> : <valore>. Il principio è tale e quale a quello già studiato nella lezione dei dizionari in Swift.
    A sinistra viene sempre rappresentata la chiave o attributo, poi con i due punti si fa iniziare la parte relativa all’informazione associata a tale chiave/attributo.
  • La virgola va inserita tra ogni chiave:valore ad eccezione dell’ultima coppia.

Esempio 0. Descrizione di un oggetto JSON semplice:

Queste sono le informazioni di base per leggere un qualsiasi tipo di file JSON. Comunque voglio fare delle considerazioni nel caso in cui non avessi mai visto o utilizzato la sintassi JSON.

Voglio farti notare come all’interno del primo blocco, identificato dalla prima e ultima parentesi graffa, è presente un sotto blocco che nasce come valore associato alla chiave “giuseppe” (o “oggetto” se consideri l’esempio 0).

Quindi un oggetto JSON può essere composto da più sotto blocchi annidati.

Esempio 1. aggiungi alla struttura “giuseppe” le capacità (skills) nei diversi linguaggi di programmazione:

Una volta capito il gioco delle parentesi, simile tra l’altro all’avere degli if annidati in un codice, è facile capire come il JSON non si spinga oltre per complessità.

Curiosità: Il fatto che il JSON sia l’acronimo di JavaScript Object Notation non deve trarti in inganno. JavaScript non è Java, sono due linguaggi completamente differenti e l’uno non è correlato in nessuna maniera all’altro.

I creatori di JavaScript o JS l’hanno chiamato in questo modo solo per accaparrarsi una fetta di mercato dato che in quegli anni Java dominava, e domina, il settore dell’IT.

Array di elementi in JSON

Qualcosa che potrebbe un po’ stravolgere il concetto di semplicità è la presenza di un array di elementi.

Maaa, niente paura! sSe, come lo spero, provieni già da un linguaggio di programmazione (anche perché non capirei come sia finito su un tutorial che tratta qualcosa di oscuro come JSON :D), la storia è sempre la stessa.

Un array di elementi, o dizionario, viene raffigurato tramite la notazione con parentesi quadre. Ogni elemento dell’array è suddiviso dall’altro tramite virgola.

Esempio 2. Un algoritmo genera un JSON contenente la lista delle armi utilizzate da un personaggio di un videogioco. Le armi sono suddivise per tipologia:

I tipi di dati permessi

Ecco la lista dei dati permessi da un file JSON:

  • Array: una lista di elementi racchiusi dalle parentesi quadre.
  • Boolean: true o false.
  • Number: tutti i numeri reali.
  • String: caratteri e unione di più caratteri.
  • Oggetti

Cosa contraddistingue JSON da XML

Se già conosci XML, o l’hai visto utilizzare in alcune applicazioni tipo feed generator o feed reader (ne ho parlato in questo tutorial -> Creare un RSS App in Swift – blog Reader), sai quanto sia confusionaria la sua sintassi.

JSON è simile all’XML perché:

  1. Entrambi sono linguaggi gerarchici o hierarchical, ovvero all’interno di un item o oggetto è possibile trovare altri item/oggetti.
  2. Sono self-describing, ogni valore ha un nome che descrivere ciò che rappresentano (es. “skills” nell’esempio 1).
  3. Possono essere letti o parsed dalla maggior parte dei linguaggi di programmazione (incluso Swift).
  4. Vengono utilizzati come file di ritorno dalla maggior parte delle richieste httpWebRequest (AJAX).

JSON non è simile all’XML perché:

  1. JSON è less verbose, ovvero utilizza una quantità bassissima di lettere e caratteri per descriversi. Infatti come hai ben visto utilizza solamente i due punti e le parentesi graffe.
  2. JSON permette l’utilizzo degli array.
  3. XML utilizza le angular bracket con il tag ad inizio e a fine oggetto per identificare un item, mentre a JSON basta inserire il nome prima di un oggetto per identificare un nuovo item.

JSON sostituirà XML?

Maybe! dico forse perché ci sono campi d’utilizzo in cui l’XML rimarrà affermato ancora per molto tempo, ma per le piccole cose e per i passaggi di dati semplici, come quelli che avvengono nella maggior parte delle applicazioni, da qui a qualche anno vedrai la ribalta di XML a favore di JSON (non è un caso che lo stesso WordPress sta allargando le sue funzionalità implementando nuove funzionalità tra cui l’utilizzo del JSON).

Tra l’altro JSON, per la sua somiglianza alle strutture dei linguaggi di programmazione, è molto più semplice da interpretare, con un linguaggio orientato agli oggetti, rispetto ad un file XML.

Adesso te ne darò dimostrazione!

Come funziona la lettura o parsing di un file JSON

I file JSON vengono restituiti, nella maggior parte dei casi, in risposta ad un evento generato per richiesta. Ad esempio, siti web come Github mettono a disposizione il loro sistema di ricerca file e progetti anche a programmi di terze parti. In questo modo, dato un url di riferimento (https://api.github.com/search/repositories?q=COSAVUOICERCARE) opportunamente modificato, restituisce una pagina JSON con tutti gli argomenti ricercarti.

Un altro servizio che offre la possibilità di interagire con il proprio sistema è openWeathermap, per le informazioni sul meteo in tempo reale. openWeather permette di creare un file JSON con tutte le informazioni relative a temperatura, vento, umidità ecc di una particolare zona passata come parametro di un certo url (http://api.openweathermap.org/data/2.5/weather?q=NomeCittà,CodiceStato).

Non mi hai capito? proviamo insieme a generare un file JSON.

Generare un file JSON tramite richiesta manuale

Prova ad utilizzare il servizio di openWeathermap per generare il file JSON relativo alle temperature della tua città. Segui questi semplici passaggi:

  1. Da Ottobre 2015 è necessario registrare un account per utilizzare le API di openweathermap.org. Quindi, registrati ora.
  2. Vai alla pagina del tuo account e copia la tua API KEY.
    openweathermap API key Dev
  3. Prendi il link:
    1. http://api.openweathermap.org/data/2.5/weather?q=NomeCittà,CodiceStato&APPID=LaTuaApiKey
  4. Sostituisci a “NomeCittà” il nome del tuo paese/città, a “CodiceStato” quello relativo allo stato in cui si trova la città o paese e ad “LaTuaApiKey” la stringa che hai nel tuo pannello utente.
    Per codice intendo le lettere identificative, ad esempio per l’Italia è IT.
  5. Apri una nuova pagina di safari ed incolla l’url modificato nella barra degli url. Nel mio caso l’url è:
    1. http://api.openweathermap.org/data/2.5/weather?q=Pedara,it&APPID=ilTuoValore
generazione manuale di un file JSON tramite api openweathermap

In questa immagine manca il valore dell’APPID. Nelle nuove versioni devi inserire obbligatoriamente il campo APPID.

Non ti sembra poco ordinato questo file JSON?

A me si! Ma non preoccuparti il motivo risiede nell’ottimizzazione che fanno alcuni programmi per evitare la generazione di file pesanti da caricare (gli spazi tra le parole rallentano la scrittura di un file).

Per poter leggere un file in modo ordinato, esistono dei programmi chiamati JSON Formatter/Validator che ti permettono di controllare l’esattezza della sintassi del file in questione e di riordinarlo per una lettura user-friendly.

Io utilizzo questo: JSON Formatter. Ti basta andare su questa web app, incollare il codice JSON e cliccare su Process, il risultato è strabiliante:

JSON Formatter e validator

Ecco il file correttamente ordinato:

A mio avviso il seguente file risulta abbastanza semplice da leggere. A parte alcuni parametri che potrebbero risultare poco chiari per via della non conoscenza della meteorologia, altri risultano estremamente semplici da decodificare.

L’oggetto “weather” è quello che ti interessa per le informazioni sul meteo. Weather è un array (se lo guardi bene il suo valore inizia con una parentesi quadra) che al suo interno contiene un oggetto composto da delle coppie chiave/valore che descrivono il meteo della tua città:

Ad esempio, alla chiave “main” è associato il valore del meteo: “Clouds” (da me in questo momento è nuvoloso, quindi ha azzeccato) e sotto, alla chiave “description“, la descrizione dettagliata della situazione che dovrei avere nel mio paese (scattered clouds).

Solo per curiosità, ecco come si presenterebbe in formato xml:

Generare un file JSON da Web con il linguaggio Swift

I passaggi che hai fatto manualmente per la generazione di un JSON, contenente i dati meteorologici della tua zona, verranno fatti in automatico dall’applicazione che adesso andrai a realizzare.

In definitiva, quando un servizio online ti da la possibilità di generare un file JSON i passaggi da fare sono:

  1. Richiesta di generazione o HTTP Request
  2. Validazione e deserializzazione della risposta
  3. Conversione del dato JSON in un oggetto del linguaggio di programmazione Swift per il trattamento da parte dell’applicazione

L’applicazione di base per la lettura del meteo

Crea un nuovo progetto Single View Application e assicurati di aver selezionato il linguaggio Swift.

Nell’interfaccia principale, inserisci 2 UILabel, una sotto l’altra, che utilizzerai per la visualizzazione del meteo della tua città e della descrizione del meteo. Crea anche le relative IBOutlet per interfacciare il codice con la grafica.

La tua applicazione dovrebbe essere qualcosa di simile a questo:

App meteo e lettura json linguaggio swift

Se dovessi avere qualche problema, scendi sotto e a fine tutorial trovi il download del progetto. Il progetto, per l’interfaccia, fa uso dei vincoli di Auto Layout e delle Stack View.

HTTP Request e download file JSON con il linguaggio Swift

Il primo passaggio da fare è quello della connessione con il servizio openweathermap.

La richiesta ad una pagina è abbastanza semplice da generare con il linguaggio Swift. Sono necessari semplicemente l’url e una classe, chiamata Data, che provvede a connettersi all’url ed a scaricarne il contenuto.

Per semplificare tutta l’operazione ho creato una funzione ad hoc che ti invito ad utilizzare ed analizzare. Nel tuo file ViewController.swift, aggiungi all’interno della classe, il seguente metodo:

La funzione è delegata alla connessione al servizio openweathermap.org. Il parametro in ingresso forComune viene utilizzato per generare l’url corretto per la richiesta del meteo del tuo comune.

Il passaggio successivo è quella della generazione della richiesta. La classe Data(contentsOfUrl:) crea una connessione con la pagina e ne scarica il contenuto. Un po’ come se prendesse la pagina e la salvasse dentro questo oggetto Data.

la sintassi guard let x = qualcosa è stata introdotta con il linguaggio Swift 2.0. Dato che la generazione dell’oggetto Data potrebbe fallire e quindi ritornare nil, il controllo guard let data = NSData(…) serve proprio a controllare che la creazione dell’oggetto Data sia avvenuta con successo. Altrimenti entra dentro il blocco else ed esce dal metodo.

Se non ti ricordi cosa fa quest’istruzione, vedi la mia lezione del corso gratuito sul linguaggio Swift: istruzione Guard in Swift.

Infine, la funzione, scrive su console un messaggio d’avvenuto download e restituisce (return) il dato scaricato. Per poter gestire in modo più funzionale questi passaggi, un sistema intelligente sarebbe stato quello dell’introduzione della gestione degli errori in Swift che ti invito ad analizzare ed implementare.

Per poter utilizzare la funzione di download, nel viewDidLoad, effettua la chiamata del metodo weather_request:

Abilitare la connessione a servizi HTTP potenzialmente non sicuri

Con iOS 9, Apple ha definitivamente bloccato qualsiasi tipo di connessione a servizi HTTP non sicuri. Questo vuol dire che le uniche connessioni, di default abilitate, sono quelle che utilizzano il protocollo HTTPS. 

Infatti, se avvii l’applicazione, noterai come viene mostrato un messaggio sulla console che, per l’appunto, ti avvisa che non può effettuare questa tipologia di connessione.

Per poter sbloccare la possibilità di connettersi a servizi HTTP, devi inserire nel file plist.info le specifiche per abilitare le connessioni non sicure.

Clicca con il tasto destro sul file Info.plist e seleziona Open As\Source Code. In fondo al file, prima della chiusura dei due blocchi finali, aggiungi:

Adesso l’applicazione dovrebbe connettersi senza problemi, ed infatti se avvii l’app, nella tua console dovrebbe spuntare uno dei due messaggi di avvenuta, o fallita, connessione.

condividi xcoding

Ho impiegato un po’ di tempo a scrivere questo tutorial, sarei davvero felice se contribuissi al mio progetto semplicemente mettendo un mi piace o follow alle mie pagine

[addtoany]

Grazie davvero :-)

Validazione e deserializzazione del Data in JSON con il linguaggio Swift

Per il momento hai un un oggetto Data che non è ancora un file JSON o meglio, lo è ma non è stato ancora trasformato nella forma che ti ho fatto vedere ad inizio tutorial. Il tipo Data è simile ad una scatola che possiede qualcosa al suo interno ma non sai di preciso cos’è finché non la apri.

Dall’introduzione al JSON, che ti ho fatto ad inizio lezione, dovresti aver capito che un file JSON è simile ad un dizionario del linguaggio Swift. Tutte le informazioni al suo interno sono organizzate tramite “chiave”:”valore”.

Dato che Data è un contenitore con qualsiasi tipo di dato al suo interno, è facile immaginare che, data la sicurezza che quell’oggetto è stato creato da un URL che genera un JSON, quel Data potrà essere tranquillamente trasformato in un dizionario.

Sotto il metodo precedente, aggiungi il seguente:

Ti ricordi quando ti ho fatto vedere che il file generato dalla richiesta alla pagina openweather veniva visualizzato in una forma compatta?

Ecco! in questo momento il Data si trova in quella forma e per tanto deve essere trasformato o, per meglio dire, serializzato.

In tuo aiuto arriva la classe JSONSerialization che provvede a trasformare un Data in un JSON formattato e validato. Dunque, all’interno della funzione json_parseData, aggiungi il seguente codice:

Il metodo jsonObject(with:) ritorna un oggetto Any in cui al suo interno vi è il JSON correttamente serializzato o verrà generata un’eccezione (quel try indica che il metodo può andare in throw – vedi lezione Gestione degli Errori in Swift).

Infine, dato che il JSON scaricato, hai visto che si presenta in forma di dizionario, la costante viene convertita in NSDictionary.

Adesso, nel metodo viewDidLoad, aggiungi la chiamata al metodo json_parseDate:

Per vedere il risultato di ciò che fa la funzione, subito sotto, aggiungi un print:

Benissimo! adesso la costante json conterrà tutto il contenuto del JSON scaricato e serializzato!

Conversione del JSON in un oggetto Swift

L’ultimo passaggio da fare è quello di estrapolare dall’intera costante json (che contiene tutte le informazioni) solamente i dati che ti interessano.

La costante json si trova sotto forma di NSDictionary grazie al metodo JSONSerialization che ha provveduto a inserire le opportune chiavi/valore nelle corrispettive del dizionario.

Fai attenzione perché noi siamo sicuri che il JSON è un dizionario perché l’abbiamo visto con i nostri occhi (quando hai aperto il link manualmente). Spesso i JSON possono essere anche degli Array. Quindi, prima di convertire in NSDictionary o NSArray fai un controllo sul tipo di dato che effettivamente trasporta il JSON.

Continuiamo.

Ad ogni chiave del dizionario è associato un blocco di informazioni del file JSON. Quindi scrivi:

Ti farà accedere alle informazioni contenute nel blocco weather del file JSON.

Il blocco weather però, se controlli bene il file JSON, è un array di 1 elemento e quindi il valore associato alla chiave weather dell’NSDictionary è, in realtà, un NSArray con un solo elemento.

Sotto la chiamata alla json_parseData, aggiungi:

Ricordati che un oggetto JSON è sempre rappresentato da un dizionario, quindi l’unico elemento presente nel weather_array (weather_array[0]) viene convertito anch’esso in NSDictionary.

Il dizionario weather in questo momento contiene tutte le informazioni che ti interessano sul meteo della tua città, ad esempio:

Stamperanno la situazione meteorologia (main – che nel mio caso è “Clouds”) e la descrizione dettagliata della situazione (description – nel mio caso è “overcast clouds”).

Quindi se adesso associ, i text delle due IBOutlet, a queste informazioni, avrai creato un’applicazione stile meteo app:

Download e lettura file JSON con Swift

Per giusta regola tutto il controllo sul file json e il riempimento delle due textField doveva essere inglobato in un if let. Ecco come:

Considerazioni

In questo tutorial introduttivo al Parsing JSON con il linguaggio Swift ho voluto introdurre uno dei tanti sistemi per leggere un file JSON con il linguaggio Swift. Esistono anche soluzioni già preconfezionate, come Alamofire, che semplificano di molto la realizzazioni di applicazioni che fanno largo uso delle connessioni e il recupero di file JSON.

Dove andare da qui

Ecco la lista dei tutorial che ti consiglio:

Download del progetto finale

Se hai avuto problemi con il tuo progetto, qui sotto, puoi scaricare quello fatto da me:

[sociallocker]Download DropBox[/sociallocker]

Changelog

  • 15/09/2016: Start changelog e aggiornamento a xcode 8.0 e swift 3.0. Modifiche generali al testo

Buona Programmazione!

Start typing and press Enter to search

Creare app con login online a database Parse in swiftBlurEffect e VisualEffect con Swift