Le novità introdotte con iOS 5 sono state davvero tante e qui su devAPP cerchiamo sempre il modo migliore per proporvele. In questo articolo analizzeremo la classe NSJSONSerialization, che benché non faccia parte delle novità tra le più acclamate e conosciute come ARC, Storyboard e UIPageViewController è, a mio avviso, un comodo strumento per la realizzazione di applicazioni che si interfacciano con un web service.
Come possiamo leggere dalla reference (QUI) la classe NSJSONSerialization si occupa di codificare e decodificare da e verso oggetti foundation a JSON, sembra quindi doveroso fare una premessa per spiegare cos’è JSON.
Cos’è JSON
La pagina di wikipedia (QUI) ci dice che JSON è l’acronimo di JavaScript Object Notation ed è un formato dati standardizzato per comunicazioni client server. Nato inizialmente per essere usato in javascript ha invece preso piede per via della sua semplicità anche in altri ambiti. In effetti il formato JSON non ha nulla in più dell’XML anzi, proprio la versatilità e la generalità dell’XML fa si che un parser XML sia “un tantino” più complesso di un parser JSON.
Sempre wikipedia ci fornisce un esempio di codice JSON:
{ "type": "menu", "value": "File", "items": [ {"value": "New", "action": "CreateNewDoc"}, {"value": "Open", "action": "OpenDoc"}, {"value": "Close", "action": "CloseDoc"} ] }
La sua sintassi è semplice, tra le parentesi graffe { } vengono inseriti i dizionari, mentre tra le parentesi quadre [ ] vengono inseriti gli array classici.
Nel codice qui in alto possiamo quindi distinguere la rappresentazione JSON di un dizionario dotato delle chiavi type, value e items. Il valore di quest’ultima chiave è un array contenente 3 dizionari dotati delle chiavi value e action.
Il nostro progetto
Potremmo far pratica con JSON utilizzando uno dei tantissimi siti che espongono API di comunicazione che utilizzano JSON, come ad esempio lo stesso youtube (QUI) basterebbe infatti visitare questa url:
https://gdata.youtube.com/feeds/api/videos? q=ipod+binary+clock &max-results=1 &v=2 &alt=jsonc
per ottenere in tutta risposta un perfetto JSON con tutti i dati del video richiesto (potete vedere una versione indentata del JSON di risposta QUI) ma noi vogliamo fare qualcosa di più in questo tutorial: realizzeremo infatti anche la parte server!
Creeremo una semplice app che visualizzi in una tabella un’elenco di nomi prelevandoli dal nostro webservice, inoltre cliccando sulla cella contenente il nome verrà visualizzata la schermata di dettaglio.
Per fare ciò utilizzeremo in perfetto stile iOS 5 sia ARC che storyboard.
Installazione di un server LAMP/MAMP
Per la creazione del nostro piccolo server avremo bisogno di tre cose:
- un server web Apache,
- un server db MySql
- e ovviamente il supporto PHP.
Questi tre programmi spesso vengono installati insieme portando alla creazione di un server *AMP, se tale installazione è su linux allora si chiamerà LAMP, su Mac MAMP e ovviamente su windows WAMP.
Installeremo quindi un server MAMP sul nostro mac e lo utilizzeremo per lo sviluppo dell’applicazione. Quando scriveremo la nostra applicazione reale il server dovrà essere ospitato da una server farm ma in fase di sviluppo il server locale andrà più che bene.
Per configurare un server MAMP abbiamo una comoda opportunità data dal programma omonimo (QUI) scaricate quindi ed installate MAMP… purtroppo vi installerà anche la versione PRO (a pagamento) ma basterà fare attenzione in fase di avvio assicurandosi di avviare sempre quella free.
Una volta avviato il software vedrete questa schermata:

I led verdi indicano che i due server Apache e MySql stanno lavorando correttamente. Se non si fosse già aperta potete cliccare sul pulsante “Open start page” per visualizzare la pagina principale del nostro server MAMP dalla quale possiamo poi accedere a diverse funzionalità.
Creiamo il database
Il database in questa applicazione sarà veramente molto semplice infatti conterrà una sola tabella che chiameremo “contatti” composta da 5 campi:
- id
- nome
- cognome
- data_nascita
- sesso
Nella realtà saranno probabilmente necessari più campi o più tabelle ma non cambia in ogni caso l’approccio da utilizzare.
Per creare il database utilizzeremo phpmyadmin, un frontend web per mysql. Apriamo quindi la pagina principale con “Open start page” (se l’avete già chiusa) e clicchiamo nel menù in alto su phpMyAdmin. Si aprirà la pagina principale di phpmyadmin:

Il primo passo da fare è creare un nuovo database, inseriamo quindi nell’apposita casella di testo un nome di nostro gradimento (io ho inserito “devapp_db”) e clicchiamo su “create”. Il programma mostrerà un messaggio di conferma dell’avvenuta creazione.

Se avete voglia di creare manualmente la tabella potete cliccare su “struttura”, inserire il nome della tabella (io ho digitato “contatti”) e inserire 5 come numero di field. Al click sul tasto GO apparirà la pagina dove bisognerà specificare per ciascun field il tipo di dato memorizzato ed eventuali vincoli e indici:
- id: integer, chiave primaria con autoincremento
- nome: varchar di lunghezza 255
- cognome: varchar di lunghezza 255
- data_nascita: data
- sesso: set [M,F]
Se invece volete vedere subito il risultato finale potete usare il file qui allegato (contatti.sql) che potrete importare semplicemente cliccando sulla voce “import”, quindi su “choose file” ed infine su “go”. Se avete fatto tutto correttamente riceverete il messaggio di conferma come mostrato in questa immagine:

Per assicurarci che siano stati inseriti anche i dati clicchiamo su Sql e digitiamo una query SQL per ottenere tutti i contatti inseriti:
Select * from contatti;
Clicciamo su “go” e analizziamo il risultato, che dovrebbe essere uguale a questo:

Complimenti! La realizzazione del database è terminata, passiamo ora alla prossima sezione della guida in cui genereremo il webservice in php.
Creazione del webservice
Adesso che abbiamo creato il database dobbiamo creare il web service vero e proprio, tramite la stesura di pagine php che faranno da “interfaccia” tra iOS ed il database stesso.
Apriamo quindi il nostro editor di testo preferito (smultron, textwrangler,emacs) e creiamo un nuovo file chiamandolo index.php. Questo file va salvato all’interno della cartella Application\Mamp\htdocs.
Non spaventatevi se non conoscete il php, non sarà necessario essere dei guru per capire il codice che andremo a scrivere.
Iniziamo con inserire il prototipo di una nuova classe:
nome = $nome;
}
public function setCognome($cognome) {
$this->cognome = $cognome;
}
public function setDataNascita($datanascita) {
$this->datanascita = $datanascita;
}
public function setSesso($sesso) {
$this->sesso = $sesso;
}
}
?>
Come si può intuire la classe Contatto disporrà di 4 proprietà: nome, cognome, datanascita e sesso (rispecchiano la struttura del database) e quattro metodi setter.
Il php è un linguaggio non tipizzato quindi non dovremo specificare se si tratta di stringhe, di interi o di date.
Proseguiamo dichiarando quattro variabili che conterranno i dati per la connessione al database:
Unsername e password sono quelli di default di Mamp e sono visibili nella pagina principale.
A questo punto effettuiamo la connessione a mySQL tramite le istruzioni:
$db_server = mysql_connect($db_hostname, $db_username, $db_password);
if (!$db_server) die("Unable to connect to MySQL: " . mysql_error());
Se la connessione non andrà a buon fine verrà interrotto il caricamento e visualizzato un messaggio di errore.
Proseguiamo con la scelta del database e con l'esecuzione della query:
mysql_select_db($db_database) or die("Unable to select database: " . mysql_error());
$query = "SELECT * FROM contatti";
$result = mysql_query($query);
if (!$result) die ("Database access failed: " . mysql_error());
$rows = mysql_num_rows($result);
Possiamo a questo punto iterare sull'oggetto result per ottenere ciclicamente tutti i record e creare delle istanze della classe Contatto da memorizzare in un array:
for ($j = 0 ; $j < $rows ; ++$j)
{
$row = mysql_fetch_row($result);
$contatti[$j] = new Contatto;
$contatti[$j]->setNome($row[1]);
$contatti[$j]->setCognome($row[2]);
$contatti[$j]->setDataNascita($row[3]);
$contatti[$j]->setSesso($row[4]);
}
La magia adesso avviene con una funzione predefinita di PHP 5.2, che riesce a convertire il nostro array in una stringa JSON in modo veramente semplice, infatti ci basterà scrivere:
$json_string = json_encode($contatti);
echo $json_string;
?>
Per visualizzare il risultato del nostro lavoro basterà aprire un browser e digitare http://localhost:8888/ per visualizzare questo risultato:
[
{
"cognome": "Rossi",
"datanascita": "2012-01-01",
"nome": "Mario",
"sesso": "M"
},
{
"cognome": "Verdi",
"datanascita": "2012-01-12",
"nome": "Luigi",
"sesso": "M"
},
{
"cognome": "Franchi",
"datanascita": "2012-01-12",
"nome": "Franco",
"sesso": "M"
},
{
"cognome": "Neri",
"datanascita": "2012-01-22",
"nome": "Luca",
"sesso": "M"
},
{
"cognome": "Pannocchia",
"datanascita": "2012-02-01",
"nome": "Anna",
"sesso": "F"
},
{
"cognome": "Marturano",
"datanascita": "2012-02-03",
"nome": "Filomena",
"sesso": "F"
},
{
"cognome": "Luciani",
"datanascita": "2012-02-12",
"nome": "Licia",
"sesso": "M"
},
{
"cognome": "Scongiuri",
"datanascita": "2012-12-21",
"nome": "Maya",
"sesso": "M"
}
]
Non vi preoccupate se il vostro browser non indenta correttamente il testo, è normale.
E con questo abbiamo terminato lo sviluppo del nostro server, nella prossima puntata affronteremo la realizzazione del cliente iOS.
Buona programmazione a tutti!
29 Responses to “T#105 – JSON e iOS 5: creiamo il backend con JSON e PHP (Parte 1)”
16 Gennaio 2012
allemattiofantastico..l’ho utilizzato per la mia tesi di laurea!
16 Gennaio 2012
Lucanice
16 Gennaio 2012
IgnazioCPer ogni dubbio mi trovate sul forum!
16 Gennaio 2012
matteogrande!!! proprio quello che cercavo…
a quando la seconda???????? ??????
grazie!
17 Gennaio 2012
StefanoOttimo, utilizzo json per tutte le mie webapp in ext js e sencha touch, ora con la seconda parte potró fare anche le app iphone direttamente prendendo i dati json sui db esistenti!
Non ho letto la reference della classe NSJSONserialization, si possono eseguire richieste di tipo CRUD? Corto a leggere!
17 Gennaio 2012
Ignaziocciao, grazie per aver commentato. hai qualche link di applicazioni realizzate con sencha? sto cercando di fare uno studio serio sulla programmazione non nativa ma sembra che tutti ne parlino ma nessuno abbia app “serie” da mostrare.
ciao.
17 Gennaio 2012
ClaudioVorrei consigliare JSONView a chi usa Firefox, questa componente aggiuntiva permette di vedere il JASON ben indentato rendendo la lettura di quest’ultimo ben più chiara.
17 Gennaio 2012
StefanoIo realizzo praticamente solo applicazioni gestionali ovvero applicazione prettamente legate ai dati che devono gestire. In alcuni casi i clienti mi hanno chiesto di poter interagire anche con iPad e iPhone sui loro dati e poiché io sviluppo prettamente con ExtJs/javascript lato client e php/mysql lato server ho scelto sencha touch per i client mobili. Sono applicazioni private tuttavia realizzate su misura e non disponibili a tutti, dovrei permetterti di entrare su una e farti visualizzare i dati del cliente, capisci?
Non vedo l’ora di seguire il seguito di questo articolo perchè posso sfruttare la mia pluriennale esperienza nel lato server per creare finalmente qualche app per iPhone strettamente legata ad un servizio web usando appunto JSON che è semplice e veloce nello scambio dei dati!
Ciao
17 Gennaio 2012
LucaDomanda legata all’esempio per ottenere i dati in JSON dai video di YouTube, ma se io voglio ottenere le info di un singolo video, del quale conosco l”ID”, ad esempo ZGw-2lKiT34, come faccio ad ottenere la risposta JSON?? per capirsi
https://gdata.youtube.com/feeds/api/videos?q=ipod+binary+clock&max-results=1&v=2&alt=jsonc
per il singolo video, come deve essere scritto?? Grazie17 Gennaio 2012
Lucami rispondo da solo dopo una ricerchina (non era nella pagina principale delle API) per il video in question, ad esempio era
https://gdata.youtube.com/feeds/api/videos/ZGw-2lKiT34?v=2&alt=jsonc
17 Gennaio 2012
LucaOttimo suggerimento, non lo conoscevo! E supremo avatar!
18 Gennaio 2012
Tech@Stefano
guarda che i dati in formato JSON si potevano già gestire prima con Objective-c, perché ci sono diverse classi che implementano la serializzazione e deserializzazione ed alcune anche molto performanti.
18 Gennaio 2012
Ignaziocconcordo, infatti ho inserito in fondo un link ad un benchmark delle varie possibilità.
3 Febbraio 2012
PBmobile77Salve, Ciao a tutti.
Ho un problema: ho creato la tabella con i contatti e il file index.php come detto ma quando nel browser lo faccio partire “http://localhost:8888/” per controllare il risultato non mi esce niente (pagina bianca, senza nemmeno ev errori…).
Non capisco dove potrei aver cannato. Ho un problema di php sul mio macbook? non so….
16 Febbraio 2012
sterzosmanettoneSi può fare un esempio al posto di ricevere i dati da jSON, si scrive….
9 Marzo 2012
DomenicoCiao.
Sto cercando di realizzare la mia prima applicazione per iphone.
volevo sfruttare il database in mysql del mio sito. Ho realizzato il webservice come hai indicato e se lo pubblico sul webserver funziona.
Posso permettermi solo un Xcode 3.1, posso lavorare con Json?
Grazie
20 Novembre 2012
GiacomoSalve.
Ottima guida, ma il file php con i dati per l’accesso al database non è poco sicuro?
Se qualcuno riesce ad accedere al file può rubare il dataBase o cancellarlo.
Come si può rendere più sicuro questo sistema?
grazie
20 Novembre 2012
Ignaziocè lo standard..qualsiasi cms (wordpress, joomla, drupal, wikimedia…) ha un file php con dentro i parametri di configurazione. diciamo che il server web non dovrebbe MAI darti accesso al file php così com’è ma lo passa sempre all’interprete e ti ritorna l’html.
se un giorno dovessero scoprire un modo per farsi restituire da apache (il web server) il file php sorgente allora potremmo dire addio a metà del web in un solo giorno.
21 Novembre 2012
Giacomook grazie!!!
22 Gennaio 2013
Alexil link per il file contatti.sql non funziona. potete postarne un’altro.
Grazie 😉
24 Gennaio 2013
AlexMa come faccio se volessi fare in modo che l’app si colleghi a un sito internet.
Cioè:
io ho il sito su altervista. Come posso caricare il file contatti.sql sul mio sito?
Grazie 😉
7 Agosto 2013
marcoCiao,
Ti dispiacerebbe postare il file php del codice, perché ci sono innumerevoli caratteri sporchi di formattazione(ho già provato con più browser) ed io di php conosco molto poco.
Grazie
13 Settembre 2013
antonioCiao,
come già detto nei commenti precedenti si potrebbe postare il file index.php del codice, perché ci sono innumerevoli caratteri sporchi di formattazione.
Grazie
14 Settembre 2013
antonioCODICE PHP CORRETTO PER IL WEBSERVICE
spero vi posso essere utile.
nome = $nome;
}
public function setCognome($cognome) {
$this->cognome = $cognome;
}
public function setDataNascita($datanascita) {
$this->datanascita = $datanascita;
}
public function setSesso($sesso) {
$this->sesso = $sesso;
}
}
?>
<?php
//dichiarazione variabili che conterranno i dati per la connessione al database
$username = "root";
$password = "root";
$hostname = "localhost";
//connection to the database
$dbhandle = mysql_connect($hostname, $username, $password)
or die("Unable to connect to MySQL");
echo "Connected to MySQL”;
//select a database to work with
$selected = mysql_select_db(“devapp_db”,$dbhandle)
or die(“Could not select devapp_db”);
//execute the SQL query and return records
$query = “SELECT * FROM contatti”;
$result = mysql_query($query);
if (!$result) die (“Database access failed: “. mysql_error());
//fetch tha data from the database
$rows = mysql_num_rows($result);
for ($j = 0 ; $jsetNome($row[1]);
$contatti[$j]->setCognome($row[2]);
$contatti[$j]->setDataNascita($row[3]);
$contatti[$j]->setSesso($row[4]);
}
print(json_encode($contatti));
mysql_close();
?>
18 Settembre 2013
RedazioneCodice aggiornato.. ogni tanto vengono sostituiti <, > e & con i rispettivi in HTML
(grazie Antonio).
14 Dicembre 2013
WalterCi sono alcune imprecisioni nel codice php…
I metodi set non sono necessari visto che le proprietà della classe sono pubbliche. In alternativa (consigliato) si potrebbe rendere le proprietà private ed aggiungere il getter.
L’estensione mysql (non più aggiornata e nata per il php4) dovrebbe essere rimpiazzata dall’utilizzo di mysqli o PDO che hanno un set di funzionalità maggiore ed una possibilità di espansione maggiore.
In linea di massima si dovrebbe evitare di utilizzare la wildcard sulle select, in un web service poi credo sia fondamentale.
My2C.
14 Dicembre 2013
WalterAltra piccola cosa che noto solo ora…
Il mysql_num_rows per eseguire il ciclo for può essere totalmente saltato utilizzando un ciclo while a vantaggio della leggibilità :
$contatti = array();
While($row = mysql_fetch_object($result)){
$contatti[] = array(
‘nome” => $row->nome,
‘cognome” => $row->cognome,
‘dataNascita” => $row->dataNascita,
‘sesso’ => $row->sesso
);
}
Echo json_encode($contatti);
In questa maniera il codice è più chiaro. Abbiamo eliminato anche la necessità della classe Contatto che comunque non funzionava non avendo dei return nei metodi.
Naturalmente per un’espansione e miglior gestione futura utilizzare un oggetto contatto sarà la cosa più comoda.
My2c
14 Dicembre 2013
WalterScusate non avevo notato la creazione dell’istanza contatto nell’iterazione. Quindi rimangio il fatto che la classe non funzioni
Quindi ecco il ciclo while corretto
$contatti = array();
While($row = mysql_fetch_object($result)) {
$contatto = new Contatto;
$contatto->nome = $row->nome;
$contatto->cognome = $row->cognome;
// etc…
$contatti[] = $contatto;
}
Echo json_encode($contatti);
15 Dicembre 2013
IgnaziocGrazie per i commenti, come si vede bene dal codice non sono un programmatore php inoltre questo articolo usa mysql in maniera non proprio ortodossa, ci sono adesso decine di framework per gestire il database in maniera più corretta (ORM). Ho creato la classe “contatto” perché in php si tende ancora troppo spesso al procedurale e invece volevo evidenziare la possibilità di gestire le classi.
Detto ciò se qualcuno volesse fare la versione “2.0” dell’articolo utilizzando PDO sarei felicissimo 😉