Eccoci con un nuovo tutorial dedicato alla programmazione per iPhone. Oggi vedremo come integrare nelle nostre applicazioni iPhone (e iPad) una tecnologia molto utilizzata, specialmente in ambito web: stiamo parlando di XML. Vedremo, quindi, come leggere un file XML, da cui preleveremo delle informazioni che abbiamo salvato. Questa operazione verrà eseguita in locale (ovvero il file xml sarà all’interno del nostro progetto), ma nulla ci vieta di avere il file caricato su un server web da cui accediamo tramite la nostra applicazione.
1. Cosa è XML?
XML è un metalinguaggio (in quanto non è un linguaggio di programmazione vero e proprio) di markup, ovvero un linguaggio che consente di estendere o controllare il comportamento di altri linguaggi. Il linguaggio di markup più famoso è sicuramente l’HTML, che ha molte analogie con l’XML.
XML è l’acronimo di eXtensible Markup Language, da cui possiamo capire la caratteristica fondamentale di questo linguaggio: ci permette di creare tag personalizzati, in base alle nostre esigenze.
Sarà più semplice comprendere come funziona questo linguaggio mediante un esempio:

La prima riga definisce la versione di XML in uso e la codifica utilizzata (secondo le norme ISO). Dalla seconda riga in poi, invece, troviamo dei tag personalizzati, che vanno a modellare i dati a nostro piacimento.
Possiamo vedere come abbiamo definito il tag generale “studenti”, che viene iniziato alla seconda riga e concluso all’ultima. Nel mezzo troviamo, invece, altri tag, che riportano le informazioni che vogliamo memorizzare, per poi utilizzarle a nostro piacimento.
Ci sono alcune piccole regole da rispettare nella sruttura XML:
- I tag non possono iniziare con numeri o caratteri speciali e non possono contenere spazi.
Corretti:, ,
Errati: <&soldi>, <12peso>, - I tag devono essere bilanciati (ogni tag aperto deve essere chiuso)
Corretto:Andrea
Errato:Andrea - I tag non devono contenere errori di annidamento.
Ecco alcuni esempi errati:
- Si possono inserire degli attributi all’interno dei tag; la struttura sarà quindi la segente:
Valore
I nostri elementi, quindi, potranno essere scritti anche nella seguente maniera:
Questa struttura è del tutto uguale a quella precedente. Notate che in questo caso non abbiamo usato il tag di chiusura, ma abbiamo inserito “/” all’interno del tag stesso proprio per indicare che quel tag non ha elemento di chiusura. Quello che cambierà sarà solamente il modo di leggere i valori via codice.
2. XML nell’SDK di iPhone
Per ora abbiamo fatto una panoramica su XML in generale, presentando gli aspetti fondamentali di tale linguaggio. Ma come possiamo integrarlo con le nostre applicazioni? L’oggetto che si occupa di recuperare i dati da un file XML viene detto parser.
Esistono vari tipi di parser (diversi per linguaggi e tecnologie), noi andremo ad utilizzare SAX. La caratteristica di questo parser sta nel fatto che processa i documenti linea per linea: dati a cui si è acceduto in precedenza non possono essere riletti senza la rielaborazione dell’intero documento. Può essere uno svantaggio, ma è l’unico parser disponibile nell’SDK per iPhone!!
3. Creiamo un nuovo progetto
Aprimo Xcode e selezioniamo “File -> New Project”. Nel menù che ci appare selezioniamo “View-Based Application”, clicchiamo su “Choose…”, immettiamo come nome “xmlTutorial” e facciamo clic su “Save”. Abbiamo così creato il nostro nuovo progetto.

In questo tutorial utilizzeremo la vista e la classe che XCode ha già definito per noi. Prima di definire l’aspetto grafico, però, dichiariamo i componenti che ci servono. Apriamo il file “xmlTutorialViewController.h” e modifichiamolo così:
#import
@interface xmlTutorialViewController : UIViewController {
IBOutlet UITextView *textArea;
NSString *path;
}
-(IBAction)avviaParsing;
@end
Abbiamo dichiarato una UITextView (riga 4) in cui inseriremo i dati letti dal file xml, un’azione (riga 6), che andrà collegata ad un bottone (tale azione farà iniziare il processo di parsing) e una stringa che conterrà il percorso del file xml.
Salviamo il file (“File -> Save”).
4. Creiamo la struttura grafica
Apriamo ora il file “xmlTutorialViewControlle.xib”, che avvierà Interface Builder. Nella nostra applicazione, inseriamo un bottone e una TextView, di dimensioni abbastanza ampie, in quanto dovrà contenere tutti i valori letti dal nostro file xml. Dovreste ottenere un risultato come questo:

Ora, selezionando l’ UITextView, entriamo in “Attributes Inspector”, togliamo quindi la spunta da “Editable”:

questo perchè non vogliamo che l’utente possa modificare i valori presenti nella TextView (ovvero deve essere di sola lettura).
Dal pannello dei documenti (“Tools -> Reveal in Document Window”) selezioniamo “File’s Owner”, ovvero la classe che gestisce il nostro file.

Apriamo il “Connections Inspector” e qui, potremo vedere alcuni elementi, compresi i due che abbiamo definito noi all’inizio del nostro progetto. Colleghiamo “textArea” con la UITextView presente nella nostra vista, e l’azione “avviaParsing” con il bottone: quando apparirà il menù con tutte le azioni disponibili, selezioniamo “Touch Up Inside”. Se avrete eseguito tutto correttamente avrete un pannello che si presenterà così:

Abbiamo terminato la creazione della struttura grafica. Possiamo salvare tutto e chiudere Interface Builder.
5. Scriviamo il codice necessario
Prima di procedere con il codice necessario, dobbiamo inserire all’interno del progetto il file xml con i nostri dati, semplicemente trascinandolo all’interno di “Resources” in “Groups & Files”. Se avete capito la struttura di tali file, potete creare uno a vostro piacimento (fate attenzione a salvarlo con estensione .xml), altrimenti potete utilizzare nel vostro progetto il nostro file di esempio.
Apriamo ora il file “xmlTutorialViewController.m” e definiamo il seguente metodo:
// Metodo eseguito all'avvio della vista
- (void)viewDidLoad {
[super viewDidLoad];
// definiamo il percorso del file xml
NSString *pathProgetto = [[NSBundle mainBundle] bundlePath];
path = [[NSString alloc] initWithString:[pathProgetto stringByAppendingPathComponent:@"dati.xml"]];
}
Questo metodo viene eseguito all’avvio della vista e ci permette di definire dei comportamenti che devono essere eseguiti prima di ogni altra cosa. Con le due istruzioni che vedete nelle righe 5 e 6, definiamo il percorso del nostro file “dati.xml”: esso viene cercato all’interno della cartella del nostro progetto. Queste istruzioni sono molto importanti, in quanto non viene definito un percorso assoluto (soluzione sempre sconsigliabile e spesso errata), ma viene definito il percorso effettivo in cui si trova il file.
Dobbiamo ora definire l’azione che viene eseguita quando premiamo sul pulsante. Ecco il codice da inserire:
-(IBAction)avviaParsing{
//Bisogna convertire il file in una NSURL altrimenti non funziona
NSURL *xmlURL = [NSURL fileURLWithPath:path];
// Creiamo il parser
NSXMLParser *parser = [[ NSXMLParser alloc] initWithContentsOfURL:xmlURL];
// Il delegato del parser e' la classe stessa (self)
[parser setDelegate:self];
//Effettuiamo il parser
BOOL success = [parser parse];
//controlliamo come è andata l'operazione
if(success == YES){
//parsing corretto
} else {
//c'è stato qualche errore...
}
// Rilasciamo l'oggetto NSXMLParser
[parser release];
}
Le prime due istruzioni (righe 3 e 5) ci permettono di definire il parser, partendo dal percorso del nostro file. Alla riga 9 avviamo il processo di parsing, salvando il risultato in una variabile booleana: se essa vale YES la conversione si è conclusa senza errori, altrimenti c’è stato un errore (che potrebbe essere dovuto ad errori nella struttura del file xml oppure ad errori di scrittura del codice).
Come potete vedere non si tratta di codice complesso, sono poche istruzioni che dovrebbero risultarvi chiare.
La parte che viene ora è quella che si occupa di leggere i dati dal file xml. Iniziamo inserendo questo metodo:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict {
if ([elementName isEqualToString:@"studenti"]){
[textArea setText:[[NSString alloc] initWithFormat:@"%@\nInizio studenti",textArea.text]];
NSLog(@"ok");
}
else if([elementName isEqualToString:@"studente"]){
[textArea setText:[[NSString alloc] initWithFormat:@"%@\nNuovo studente",textArea.text]];
}
else if([elementName isEqualToString:@"matricola"]) {
[textArea setText:[[NSString alloc] initWithFormat:@"%@\nMatricola: ",textArea.text]];
}
else if([elementName isEqualToString:@"cognome"]) {
[textArea setText:[[NSString alloc] initWithFormat:@"%@\nCognome: ",textArea.text]];
}
else if([elementName isEqualToString:@"nome"]) {
[textArea setText:[[NSString alloc] initWithFormat:@"%@\nNome: ",textArea.text]];
}
}
Come potete osservare, vi sono una serie di controlli if, che vanno a testare l’elemento corrente, per riconoscerlo e per scrivere una stringa adeguata nella textArea che abbiamo predisposto. Questo processo è possibile perchè conosciamo a priori la struttura del file xml: questo è quasi sempre vero, in quanto sarebbe quasi impossibile leggere un file xml di cui non conosciamo la struttura interna.
Il metodo viene, ovviamente, richiamato ogni volta che il parser incontra un nuovo elemento, cioè l’apertura di un tag.
Per completare il nostro programma mancano solo due metodi:
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
[textArea setText:[[NSString alloc] initWithFormat:@"%@%@",textArea.text,string]];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
[textArea setText:[[NSString alloc] initWithFormat:@"%@\nFine elemento: %@",textArea.text,elementName]];
}
Il primo viene richiamato quando il parser incontra un valore racchiuso tra due tag (l’informazione vera e propria). Nel nostro caso ci limitiamo a inserirla nella textArea, però potreste fare delle operazioni più o meno complesse sulle informazioni che leggete dal file.
L’ultimo metodo, invece, viene richiamato quando il parser incontra un tag di chiusura. Anche in questo caso l’unica azione che faremo sarà quella di inserire una stringa nella textArea.
Possiamo finalmente cliccare su “Build and Go!” e testare la nostra applicazione funzionante!


35 Responses to “T#042 – Come utilizzare XML nelle nostre applicazioni iPhone (SDK)”
17 Maggio 2010
DevTutorial #16 – Come utilizzare XML nell’iPhone SDK - Bubi Devs[…] Leggi il tutorial completo su devAPP Condividi tweetmeme_url = 'http://www.bubidevs.net/2009/05/22/devtutorial-16-come-utilizzare-xml/'; (function() { var s = document.createElement('SCRIPT'), s1 = document.getElementsByTagName('SCRIPT')[0]; s.type = 'text/javascript'; s.src = 'http://widgets.digg.com/buttons.js'; s1.parentNode.insertBefore(s, s1); })(); […]
17 Maggio 2010
paolinoveramente utile!
Se possibile… potete scrivere qualche tutorial sul parsing di dati xml su uno stream socket? Avrei neceesità di leggere dei dati da un server in xml (non in un file ma in uno stream) e restituire i dati letti in una tabella sull’iphone…. 🙁
17 Maggio 2010
AlenCiao scusate ma sto impazzendo…come fo a prendere da un file xml solo quello che mi serve?mi sto sbattendo e vedo che anche nel vostro progetto se aggiungo qualche riga nel file.xml quest’ultima viene inserita nel parser finale(come se fosse tutto insieme).. ho ricreato un file ho la struttura e tutto ma quando avvio il parser viene visualizzato tutto quello che ho nel file.xml…help
17 Maggio 2010
Andrea Busiciao, non ho ben capito il tuo problema. Che tipo di elementi hai aggiunto nel file XML? Quelli già presenti o ne hai definiti di nuovi?
17 Maggio 2010
Alenne ho definiti altri…es: il vostro file xml. è cosi :
Rossi
Paolo
Via Milano
ok io ho aggiunto , creando la struttura con ” if element name is equal to string” mi viene tutto regolare, è semplicemente un aggiunta…ok..PERO..se io avessi un file xml con piu tag…metti…10 tag…a me per mi serve sapere e visualizzare solo il 2 °,5°,6°,10° tag..come fo?
dovrei modificare il “parser foundCharacter” e non dichiarare l’ initWithFormat:@”%@%@”, ma cosa??
Lo scopo appunto è estrapolare piu dati da file xml pe poi inserirli es in una tabella (o in questo caso nella textview)
17 Maggio 2010
Andrea Busiper TAG intendi elementi vero? ovvero, ti interessa leggere il 5° elemento “studente”?
in tal caso devi leggerli tutti, poi scorri la lista fino al 5° elemento e leggi solo quello, che è proprio quello che ti interessa..
18 Maggio 2010
EmilioCiao ho trovato la guida molto interessante..ora mi chiedevo,se volessi importare i dati in una TableView invece che all’interno una TextView come potrei farei??:)
19 Maggio 2010
AndreaE se io volessi creare un’app in cui carico i dati di un sito web?
Per esempio facciamo finta che http://www.sitoweb.it sia un sito di annunci di lavoro,come posso prendere questi annunci e caricarli nella mia app?In pratica sfruttare il database del sito per caricare i suoi dati nella mia app??
Non ho idea di come fare.Nemmeno per sapere il nome del database.
19 Maggio 2010
Andrea BusiÈ la stessa identica cosa, segui l’ultimo tutorial, vedrai che trovi quello che ti serve 😉
dipende da come sono strutturati i dati nel sito.. se disponi di un feed XML puoi seguire questo tutorial, altrimenti devi studiarti un modo ad-hoc.. dipende tutto da come ti vuoi interfacciare al sito!
27 Maggio 2010
Alenok..siccome non riesco a trovare nulla…ho provato tutti i parser found,ma niente…ho provato a mettere un null quando trova l’elemento indesiderato ma l’app si chiude(si crasha)….l’help di xcode nn mi aiuta tantissimo….come posso fare?
27 Maggio 2010
Alenok..siccome non riesco a trovare nulla…ho provato tutti i parser found,ma niente…ho provato a mettere un null quando trova l’elemento indesiderato ma l’app si chiude(si crasha)….l’help di xcode nn mi aiuta tantissimo….come posso fare?
28 Ottobre 2010
GiovanniCiao Andrea,
una domanda: come ti comporti in casi di caratteri accentanti?
L’XML che uso viene generato da una pagina .php che estrae dati da un db mysql, e spesso ho caratteri accentati!
Hai idea di come posso muovermi?
2 Dicembre 2010
DarioCiao ragazzi scusate sto impazzando per riuscire a fare il parsing di xml formattati nell’altro modo mostrato nel tutorial…
13 Dicembre 2010
roccoCiao Andrea,
scusa ma ho lo stesso problema di Alen di circa 6 mesi fa. ho questo file XML:
1
Rossi
Rocco
2
Verdi
Ugo
se io volessi far stampare solo i cognomi degli studenti come posso fare?
13 Dicembre 2010
Andrea Businon si vede il codice xml.. Comunque se si tratta di tre elementi distinti li devi leggere tutti e salvarli in una struttura che ti sei creato in precedenza, dopodichè stampi solo i cognomi che ti servono..
20 Dicembre 2010
DarioNon riesco a fare il parsing di file xml di questo tipo:
–
–
–
–
nella guida dice di cambiare il modo di leggere i valori via codice, ma non capisco come…
qualcuno mi da una mano?
Grazie
20 Dicembre 2010
Dario–
–
–
–
20 Dicembre 2010
DarioCome faccio il parsing di un file xml di questo tipo?
20 Dicembre 2010
Darioscusate non prende il codice xml… cmnq si puo vedere a questo link : http://www.google.com/ig/api?weather=Mountain+View
21 Dicembre 2010
Staff devAPP@Dario ciao, per richieste più specifiche usa il nostro forum, li c’è più spazio per discutere ed è più semplice postare codice (c’è un tag apposito) 😉
30 Dicembre 2010
Vincenzo Ferraraciao raga, una domanda banale, spero non troppo..:)
Questo benedetto NSXMLParser funziona anche con file xhtml?
29 Gennaio 2011
DavideCome scrivere l xml e relativo code per fare il parsing di una tabella a due o piu sessioni
16 Marzo 2011
Gianmarcoal posto del file dati.xml come posso caricare il file presente nel mio webserver??? (es. http://192.168.1.210/status.xml)
21 Marzo 2011
Andrea Busi@Gianmarco
si, dovresti riuscire ad eseguire il parsing anche del file in locale, funziona in remoto quindi non vedo perchè non debba funzionare in locale 😉
20 Agosto 2011
AlexCiao sono nuovo di questo mondo è trovo i vostri tutorial molto utili…. Io stavo cercando il modo per collegare una pagina web all app… cioè vorrei fare un app con una pagina che si aggiorna in base agli aggiornamenti del sito….
Non so se è questo il posto giusto ma sto impazzendo a cercare su internet… mi date una dritta???
Grazie mille
18 Ottobre 2011
barbygirlciao, io ho dei probelmi con questo tutorial. quando va a fare setText dell’UITextView l’applicazione crash, c’è una spiagazione? ho seguito tutto passo passo
21 Ottobre 2011
Andrea BusiCiao, prova a controllare bene, perchè non dovresti avere problemi. Il setText di una UITextView non da mai problemi.
Se non riesci a risolvere prova a postarci anche l’errore che ottieni 😉
1 Novembre 2011
GiuseppeHai risolto?? Grazie
2 Novembre 2011
barbygirlciao, vorrei chiedere anche io una cosa:
se io volessi scrivere anzicchè leggere dal file xml cosa dovrei fare?
L’esempio di lettura sono riuscita a farlo, ma adesso non riesco a fare las crittura
15 Novembre 2011
Lupo88Ciao…come faccio a caricare dei dati in un file XML?
28 Novembre 2011
Andrea BusiLa soluzione più semplice è quella di crearsi l’XML inserendolo in una NSString, poi utilizzare il metodo “writeToFile: atomically:” per salvarne il contenuto su disco.
Non mi ricordo se esistono delle classi (esterne) che permettono di salvare l’XML senza creare una stringa, potrebbero anche esistere senza problemi.
9 Maggio 2012
Pietro@Giovanni:
Ho letto il tuo commento (#11) e volevo chiederti se hai qualche esempio (o dritta) su come ricevere XML nel POST dall’invocazione di una pagina PHP ?
Grazie 🙂
28 Maggio 2013
lucagrazie per l’esempio, segnalo pero questo:
non state usando ARC, mi pare di capire… ma ci sono un sacco di errori di leak memory da mettere a posto, nel codice… tutte le volte che le stringhe vengono allocate poi non vengono rilasciate, andrebbe pulito un po’…
grazie comunque
luca
28 Maggio 2013
lucaPS
basterebbe cambiare i vari [NSString alloc] initWithFormat: con NSString stringWithFormat (che e’ autoreleased)
e.g.
[textArea setText:[[NSString alloc] initWithFormat:@”%@%@”,textArea.text,string]];
[textArea setText:[NSString stringWithFormat:@”%@%@”,textArea.text,string]];
26 Ottobre 2013
Nicolaciao raga, se io volessi caricare i messaggi del dispositivo in una mia app come dovrei fare?? qualcuno puo aiutarmi