Sei sulla pagina 1di 55

di WALTER DAL MUT e FRANCESCO FICILI

Corso di programmazione iPhone

Corso di programmazione
PUNTATA 1
iPhone

L ’iPhone integra
una vasta gamma
di sensori che lo ren-
che inizia qui e che
verterà sull’am-
biente di sviluppo
dono un’ottima piat- software iOS.
taforma embedded Partiamo subito con
ideale per sviluppare una breve panorami- Impariamo ad utilizzare
svariate applicazio- ca sui sensori inte- la piattaforma di sviluppo
ni anche a livello grati nell’iPhone, uno software iOS di Apple, uno
amatoriale: sono le dei quali è quello di
tanto amate App, che prossimità funzionan-
dei più innovativi ambienti
sviluppatori profes- te ad infrarossi, che di sviluppo software,
sionisti e semplici permette di ridurre che tramite l’objectiveC
appassionati realiz- la luminosità (se non
zano per venderle o di toglierla completa-
permette il rapido sviluppo
condividerle secondo mente) del display e di applicazioni di diversi
la filosofia open- disattivare i controlli generi per i dispositivi
source. All’iPhone quando il telefono si “mobile” di classe iPhone,
ed alle possibilità di avvicina all’orecchio;
sviluppo che offre, con questo metodo iPod Touch ed iPad.
dedichiamo un corso si riesce a ridurre il Prima puntata.

Elettronica In ~ Maggio 2011 107


Corso di programmazione iPhone
Fig. 1 - Da sinistra una
panoramica dell’iPhone
4G e dell’iPhone 3GS.

consumo della batteria, garantendo una lunga ne realizzati ad oggi. L’iPod touch è il fratello
durata, e ad evitare pressioni involontarie sul- minore dell’iPhone, è molto utilizzato dagli
lo schermo touch, che comporterebbero azioni sviluppatori in quanto presenta la maggior
non desiderate. parte delle caratteristiche dell’iPhone ed ha un
Un accelerometro capacitivo è in grado di costo più accessibile; si può dire che l’iPad è
controllare i movimenti e lo stato dell’orien- un enorme iPod Touch, dotato di risoluzione
tamento del dispositivo e quindi adattare au- grafica molto elevata ma conserva le stesse
tomaticamente l’orientamento delle immagini caratteristiche peculiari.
sul display. Una bussola digitale permette di In questo corso ci soffermeremo per di più
rilevare la direzione in cui è orientato il telefo- sull’iPhone, ma i codici possono essere esegui-
no; a questo sensore è accoppiato un ricevito- ti nativamente anche su iPod Touch, mentre
re GPS, che permette la geolocalizzazione con per iPad il codice è lo stesso ma le differenze
un’elevata accuratezza. grafiche rendono necessari diversi accorgi-
Cercheremo di proporvi applicazioni il più menti, che vedremo direttamente nella lezione
possibile complete, fermo restando che la dedicata a quest’ultimo dispositivo.
rapida evoluzione dell’hardware dell’iPhone
può porre alcuni limiti; comunque il codice Sviluppare per iPhone/iPod Touch/iPad
presentato in questo corso è adeguato, a parte Per sviluppare con la piattaforma iPhone
piccole differenze che saranno evidenziate nel abbiamo bisogno solo di un Mac basato su
momento opportuno, a tutti i modelli di iPho- processore Intel; tutte le altre componenti

Fig. 2 - A sinistra iPad. Sotto il nuovo iPod 4G.

108 Maggio 2011 ~ Elettronica In


Corso di programmazione iPhone

per lo sviluppo e la simulazione sono gratu-


ite. Per fare la sintesi dei nostri progetti sul Breve storia dell’iPhone
device fisico, invece, deve essere acquistata la
licenza di sviluppo, venduta ad un prezzo di Il 9 gennaio del 2007 alle 9:42 del mattino è stato presentato a
75 € annui. Per gli scopi di questo corso non tutto il mondo un dispositivo rivoluzionario, l’iPhone. Da quel
è immediatamente necessaria tale licenza, in giorno nel quale Steve Jobs, amministratore delegato della Apple,
presentò questo dispositivo “ibrido”, che ingloba in se stesso tre
quanto il simulatore è sufficiente per almeno macro dispositivi, sono stati presentati altri tre device della stessa
il 90 % delle applicazioni che tratteremo nel famiglia. Abbiamo detto poco fa che è un dispositivo ibrido,
nostro percorso teorico. Ricordate comunque questo perché al suo interno ingloba un iPod con capacità di
riproduzione audio e video, un telefono cellulare di ultimissima
che il simulatore non è in grado di utilizzare generazione con in dotazione una fotocamera digitale ed un
gli accelorometri, il magnetometro ed il Blue- dispositivo palmare con una nuova concezione di sistema
tooth, anche se il nostro Mac ne avesse uno a operativo derivato da Mac OS X con funzionalità avanzate di GPS,
internet e molto altro.
disposizione. È importante sottolineare che
l’esecuzione dei nostri programmi avviene su
un simulatore e non su un’emulatore, quindi gio di programmazione ObjectiveC, creato
i tempi di esecuzione non sono paragonabili dalla Stepstone. ObjectiveC è uno dei primi
con quelli di quest’ultimo, vista la notevole linguaggi orientati agli oggetti e come tale
differenza dell’hardware su cui viene eseguito impone anche le sue particolarità semantiche
il nostro codice. di lettura del codice (vedremo più avanti tali
Il linguaggio utilizzato per lo sviluppo è particolarità).
l’objectiveC, secondo le possibilità offerte da
iPhoneOS (il sistema operativo dei device Ap- Introduzione ObjectiveC
ple in questione) che da ora in avanti chiame- La caratteristica principe del objectiveC, che
remo semplicemente iOS. lo distingue dal suo parente stretto, è il fatto
La domanda a questo punto potrebbe essere: che utilizza il paradigma di programmazio-
“ma cosa andremo a fare?”. Ebbene, realiz- ne orientato agli oggetti, cosa che manca al
zemo le App, una parola che oramai è nel linguaggio C, che invece utilizza il paradig-
nostro linguaggio comune proprio grazie ai ma procedurale (funzionale se preferite);
dispositivi Apple; in pratica creeremo del- vedremo più avanti quali sono le differenze
le applicazioni disegnate ad hoc per questi maggiori tra questi due paradigmi di pro-
dispositivi. Il risultato della compilazione dei grammazione. È utile comunque sottolineare
nostri codici sarà un file eseguibile che verrà che è naturalmente inseribile codice C all’in-
installato sui device, oppure sul simulatore terno di codice ObjectiveC; sarà compito del
fornitoci dalla SDK Apple. compilatore interpretare in modo corretto le
differenze tra i linguaggi. Tratteremo nel det-
Perchè ObjectiveC taglio questa situazione quando utilizzeremo
Abbiamo detto in precedenza che il linguag- la libreria DBMS sqlite3, nel capitolo dedicato
gio di programmazione che andremo ad alla persistenza dei dati sul dispositivo.
utilizzare è l’objectiveC, ossia un’estensione Prima di parlare del mondo OOP (Object
del linguaggio più famoso al mondo: il C, Oriented Programming) dobbiamo assoluta-
scritto da Dennis Ritchie oramai nel lontano mente fissare alcuni concetti di C necessari a
1972. Questa è una scelta che fa proprio parte molte trattazioni che affronteremo, quindi non
del core di tutti i sistemi che usano MAC OS, perdiamo tempo e lanciamoci in una digres-
un’eredità della Next Step fondata da Steve sione sulle conoscenze base di C necessarie
Jobs in persona quando venne “licenziato”, allo sviluppo.
come direbbe lui, dalla Apple, dopo un solo
anno dalla sua “esplosione”. Linee guida C per iOS
In questo suo periodo sfortunato (per modo Innanzitutto è necessaria la conoscenza
di dire...) Jobs fondò la Next Step ed acquistò dell’aritmetica dei puntatori in C e del loro
da tali Bred Cox e Tom Love il loro linguag- utilizzo, in quanto in ObjectiveC lavoreremo

Elettronica In ~ Maggio 2011 109


Corso di programmazione iPhone
concetti in ObjectiveC che sono legati a dop-
Listato 1 - Dichiarazione di una classe, pseudo-linguaggio pio filo con il linguaggio di programmazione
class Macchina //definizione della classe più utilizzato al mondo e che nel mondo
{ dell’elettronica la fa da padrone.
double velocita; //proprietà velocità
string colore; //proprietà colore
Intro OOP
/** La programmazione orientata agli oggetti sarà
* Metodo per impostare la velocità
*/ il cuore pulsante delle nostre applicazioni,
void setVelocita(double velocita) quindi prima di entrare nel vivo di iPhone
{
this->velocita = velocita; Programming dobbiamo vedere un po’ di
} concetti su questo particolare paradigma di
/**
programmazione. Non si possono elencare le
* Metodo per sapere la velocità differenze che intercorrono tra un linguaggio
*/ OOP ed uno procedurale, in quanto sono
double getVelocita()
{ proprio approcci differenti; la chiave di distin-
return this->velocita; zione nasce proprio dal fatto che una classe,
}
cioè la definizione di un oggetto, incapsula in
void setColore(string colore) sé sia le variabili (chiamate proprietà) che le
{
this->colore = colore;
funzioni (chiamate metodi) che lavorano sui
} dati contenuti nell’oggetto.
Per spiegare questo concetto possiamo pen-
string getColore()
{ sare ad una macchina; la definizione di essa
return this->colore è fornita dalla classe Macchina, la quale ha
}
} //Fine della classe delle proprietà, che sono il colore, la velocità
e così via. La macchina avrà anche dei meto-
di, che sono per esempio accelera, frena, ecc.
solo con riferimenti a oggetti; deve quindi Questi metodi accederanno a proprietà, come
essere chiaro cosa sono e qual è la loro arit- ad esempio la velocità. Il passaggio da una
metica. Iniziamo ricordandoci che ogni qual classe ad un oggetto avviene quando creiamo
volta in C allochiamo una porzione di me- quest’ultimo, quindi lo allochiamo; a quel
moria dinamicamente, tramite funzioni come punto l’oggetto finisce in memoria.
“malloc”, “calloc” e “realloc”, noi sviluppatori Vediamo adesso una definizione della classe
abbiamo l’obbligo di liberare la memoria, Macchina, allo scopo di fissare questo concet-
tramite la funzione “free”, non appena termi- to; lo facciamo utilizzando uno pseudo-lin-
niamo l’utilizzo delle variabili allocate dina- guaggio di programmazione da noi inventato,
micamente; se così non fosse pagheremmo lo che ci permetterà di evidenziare i costrutti
scotto di un “memory leakage”, ovvero una chiave, saltando particolarità intrinseche di un
perdita di memoria che non potremmo utiliz- linguaggio OOP vero e proprio. Riferiamoci al
zare per altre variabili eventualmente alloca- Listato 1.
bili in futuro. Questo è il primo concetto fon- Da questo “snippet” (frammento) di codice
damentale da ricordare, soprattuto per questi vediamo la dichiarazione della classe Mac-
device embedded che non hanno diversi GB china nella prima riga; nel corpo della classe
di RAM disponibile come nei nostri computer, osserviamo le due proprietà, che sono la
per intenderci l’iPhone 3GS ha 256 MBytes di velocità ed il colore della macchina. Dopo
RAM, quindi capite anche voi che dimenticar- queste dichiarazioni vengono i metodi, i quali
si diversi oggetti in memoria renderà instabile accedono alle proprietà; questo è proprio il
la vostra App e il kernel di iOS la terminerà concetto che rappresenta una delle peculiarità
per evitare disservizi sul dispositivo. dell’OOP. Ritorniamo all’esempio, dove pos-
Allora che aspettate? Andate a ripassare un siamo vedere che per impostare una proprietà
po’ di C, perché presto ritroveremo diversi è stato inserito il prefisso SET. Questo per-

110 Maggio 2011 ~ Elettronica In


Corso di programmazione iPhone

Ora, vediamo invece quando una classe


Listato 2 - Allocazione e liberazione della memoria diventa un oggetto e come si può utilizzare
pseudo-linguaggio quest’ultimo con il nostro pseudo-linguaggio;
riferiamoci, perciò, al Listato 2.
Macchina *punto = new Macchina(); //primo oggetto macchina Come potete vedere, ogni oggetto ha le sue
punto->setColore(“Nero Metallizzato”); //imposto il colore personali proprietà e i metodi influiscono solo
punto->setVelocita(32.5); //Imposto la velocità
print punto->getVelocita(); //stampa 32.5 sulle proprietà dell’oggetto allocato. Fate par-
Macchina *giardinetta = new Macchina();//secondo oggetto ticolare attenzione al simbolo “*” che abbiamo
giardinetta->setColore(“Giallo”);//giallo per la Giardinetta
print giardinetta->getColore();//giallo
volutamente inserito nel nostro pseudo-lin-
print punto->getColore();//Nero Metallizzato guaggio per evidenziare l’allocazione dina-
mica di questi oggetti e del nostro comando
release punto; libero la memoria, via la punto
release giardinetta; libero la memoria, via la Giardinetta release, che serve a “rilasciare” la memoria
allocata dall’oggetto. Ma ciò è solo l’inizio del
mondo orientato agli oggetti; in particolare,
ché i metodi che impostano una proprietà si tale paradigma ha tre fondamentali proprietà:
chiamano setters, mentre quelli che informano incapsulamento, ereditarietà e polimorfismo. La
l’utilizzatore di una proprietà sono denomina- prima di queste proprietà significa che un og-
ti getters (hanno il prefisso GET). getto ne può incapsulare altri al suo interno:
ad esempio l’oggetto Macchina incapsula l’og-
getto Ruota e così via. Abbiamo visto questo
Listato 3 - Ereditarietà pseudo-linguaggio concetto con il precedente esempio utilizzan-
class Mammifero do, però, solo tipi base di variabili, a meno
{ che non consideriamo il tipo “string” come un
int eta = 15;
oggetto. In effetti è così per la maggior parte
void respira() dei linguaggi OOP, come per il nostro Objec-
{
//implementazione del metodo respira
tiveC; invece non è così per linguaggi come il
} PHP, che è un tipo di dato base.
L’ereditarietà è un concetto più difficile da
void setEta(int eta)
{ comprendere dell’incapsulamento; signifi-
this->eta = eta; ca che un oggetto può estenderne un altro.
}
Vediamo di chiarirci le idee con un esempio,
int getEta() prima di vedere più nel dettaglio questa pro-
{
return this->eta; //ritorna l’età
prietà fondamentale. Prendiamo una classe
} Mammifero e definiamo una seconda classe
} che possiamo considerare “figlia” di essa: ad
class Uomo extends Mammifero esempio la classe Uomo. Un piccolo snippet
{
void cammina()
{
//implementazione del metodo cammina Listato 5 - Utilizzo classi estese e metodi ereditati
}
} pseudo-linguaggio
Uomo *u = new Uomo();
u->respira();
u->cammina();
Listato 4 - Ereditarietà pseudo-linguaggio u->getEta(); //Scrive 15 (il valore di default)
release u; //Libera della memoria
Class Balena extends Mammifero
{ Balena *b = new Balena();
void nuota() b->nuota();
{ b->setEta(102);
//implementazione del metodo nuota print b->getEta(); //Scrive 102
} b->respira();
} release b; //libera dalla memoria

Elettronica In ~ Maggio 2011 111


Corso di programmazione iPhone
tà singola o multipla; la differenza tra queste
due tipologie è sul numero di padri che un
La storia della mela oggetto può avere: singola significa che si ha
La Apple è stata fondata nel lontano 1 aprile del 1976 da Steve un solo padre (è così per la maggior parte dei
Jobs, Steve Wozniak e Ronald Wayne ed ha sede a Cupertino linguaggi di programmazione OOP famosi,
in via Infinite Loop numero 1 92010. La società nasce dalla
passione dell’elettronica che i due Steve hanno in comune, nei
compreso objectiveC) mentre nella multipla si
primi anni settanta costruiscono dei dispositivi chiamati Blue può avere più di un padre e quindi ereditare
Box che permettevano di telefonare gratuitamente, i racconti metodi e proprietà dai diversi padri.
degli hackers più famosi del mondo sono pieni di storie su questi
dispositivi. È nel 1975 che i due iniziano a lavorare al loro primo
Il polimorfismo è la terza proprietà fonda-
computer sulla carta, questo doveva utilizzare il microprocessore mentale e significa che un oggetto può avere
Motorola 6800 ma costava 170 dollari e quindi il prezzo era diverse forme; è un concetto astratto che
proibitivo per le loro tasche, l’anno dopo però il chip 6502 entrò
sul mercato per soli 25 dollari e così Wozniak adatto il progetto
possiamo spiegare dicendo che diversi oggetti
per il 6800 per questo meno costoso microprocessore, il progetto possono realizzare in modi differenti le stesse
terminò nel 1976 e nacque quindi il computer ”Apple I”. Iniziarono funzionalità. Per fare un esempio pratico,
montando ed assemblando nel garage dei genitori di Jobs 50
Apple I che vendettero ad un negozio di computer. Questi sono
possiamo sempre prendere la nostra classe
gli albori della Apple, oggi la società ha un valore di mercato da Uomo, che realizza a modo suo il metodo
capogiro con utili e fatturato unici. Basti pensare che nell’ultimo Cammina, oltre ad una classe Leone, che ha
trimestre Apple ha fatturato quasi 25 miliardi di dollari con un
utile netto di sei miliardi.
una sua implementazione del metodo Cammi-
na; entrambe devono fornire questo metodo
obbligatoriamente.
di codice potrebbe essere quello contenuto Nei vari linguaggi di programmazione si
nel Listato 3. I metodi che possiamo applicare definisce un’interfaccia che obbliga una classe
ad un oggetto di tipo Uomo sono Respira e ad implementare il metodo personalizzato che
Cammina; su un oggetto Mammifero, invece, viene “firmato” da essa. Vediamo un esempio
si può applicare il solo metodo Respira. Una concreto, che facciamo definendo la nostra
terza classe, chiamata Balena, potrebbe avere interfaccia:
il metodo Nuota, che permette all’animale di
nuotare (Listato 4). interface Movimenti
Sottolineiamo che tutte e tre le classi (forse {
è meglio chiamarle oggetti) condividono la void cammina();
proprietà Eta (età) che rappresenta lo stato di }
crescita dell’animale in questione; in questo
caso si applica il Listato 5.
Come possiamo vedere, abbiamo chiamato
il metodo “getEta” anche sulle classi che non
Listato 6 - Implementazione metodi dichiarati
hanno definito questo direttamente; lo abbia-
mo potuto fare grazie, proprio, all’ereditarie- pseudo-linguaggio
tà. Il significato di questo principio è proprio
class Uomo implements Movimenti
il fatto che una classe figlio eredita tutte le {
proprietà ed i metodi della propria classe //devo definire il metodo cammina altrimenti
//il compilatore non ammetterà il nostro codice
padre. void cammina()
Abbiamo tralasciato un concetto fondamen- {
tale che si chiama visibilità dei metodi e delle //Implemento il metodo cammina su 2 piedi
}
proprietà; non lo svilupperemo in questo }
corso perché ai fini dell’objectiveC per iPhone
class Leone implements Movimenti
non è prioritario. Chi volesse, potrà appro- {
fondire l’argomento della visibilità per conto void cammina()
{
proprio. //implemento il metodo cammina su 4 zampe
Prima di vedere l’ultima proprietà fondamen- }
tale di OOP è necessario parlare di ereditarie- }

112 Maggio 2011 ~ Elettronica In


Corso di programmazione iPhone

Queste righe di codice riguardano la dichiara-


zione di un’interfaccia di tipo pseudo-linguag- Listato 7 - Costruttore e Distruttore pseudo-linguaggio
gio. La nostra classe Uomo si deve trasforma-
re nel modo illustrato nel Listato 6.
Il polimorfismo è un concetto difficile e class Uomo
{
sfaccettato, sul quale non è il caso di appro- //proprietà dell’oggetto
fondire. In objectiveC è rappresentato dai ...
__construct()
“protocolli”. {
Invitiamo chi volesse approfondire l’argo- print “sono nato adesso”;
mento, ad analizzare le classi astratte ed il }

polimorfismo in generale. //metodi personali


Adesso dobbiamo ancora vedere delle par- …
__destruct()
ticolarità che sono offerte in ObjectiveC: le {
categorie (categories), le proprietà (properties) print “addio mondo crudele”;
}
e i metodi statici (static methods). Iniziamo }
con gli static methods e le properties, perché li
utilizzeremo quando introdurremo i “design
patterns”. Una classe può avere metodi e pro- ma i concetti sono uguali per tutti i linguaggi
prietà di tipo statico; il significato di ciò è che orientati agli oggetti.
questi sono codivisi da tutti gli oggetti dello Alla nostra introduzione al mondo Object
stesso tipo e dalle loro estensioni; quando si Oriented manca ancora la definizione di
creano metodi statici dobbiamo ricordarci che “overload” e di “override”: queste due parole
non possiamo accedere a proprietà che non chiave arricchiscono il mondo degli oggetti,
sono statiche anche loro. Questo perchè tali ma in realtà l’overload esiste anche nei lin-
proprietà non esistono a meno che la classe guaggi procedurali come il C++, che ammette
non venga istanziata e quindi diventi un l’overload ed anche l’ovverride nel suo conte-
oggetto; per questa motivazione le proprietà/ sto OOP. Iniziamo con il concetto di Overload,
metodi statici si definiscono “di classe”, men- perché è più immediato: un linguaggio si dice
tre quelle non statiche si dicono “di istanza”. che ammette l’overload se è possibile creare
Affronteremo un esempio concreto di metodi due metodi o funzioni a seconda del contesto,
ed attributi statici quando faremo una panora- procedurale oppure orientato agli oggetti,
mica sui “design patterns”. ovvero se è possibile scriverne un numero a
Prima di passare oltre, introduciamo breve-
mente i costruttori e i distruttori degli oggetti:
si tratta di due metodi “magici” che vengono
chiamati implicitamente del nostro sistema e Listato 8 - Esempio di overload di un metodo
ci permettono di inserire del codice durante la pseudo-linguaggio
creazione di un oggetto o quando esso viene
distrutto. Un esempio, sempre sulla classe
Uomo, potrebbe essere quello visibile nel Class Uomo
{
Listato 7. void saluta(Mano *mano)
Come potete vedere, per distinguere il {
//Implementa il saluto con la mano
costrutture abbiamo messo due caratteri _ _ }
e così per il distruttore; noi non chiamiamo
void saluta(Mano *mano, MessaggioVocale *messaggio)
esplicitamente questi metodi, perché verranno {
chiamati dal compilatore a run time quando //Implementa il metodo saluto con la mano e anche
una classe viene allocata (__construct) e //un messaggio vocale
}
quando essa viene rilasciata (__destruct). }
Faremo il paragone con objectiveC quando
introdurremo gli oggetti in questo linguaggio,

Elettronica In ~ Maggio 2011 113


Corso di programmazione iPhone
App “fai da te”
Le App (ossia le applicazioni software per i dispositivi Apple) sono da condividere, quindi non a fini commerciali. Un’interessante
sempre più richieste, probabilmente perché l’ampia dotazione di particolarità del servizio è che le modifiche apportate ad
periferiche e sensori degli iPad e iPhone si presta a realizzare con una App dopo che è stata distribuita verranno applicate
essi numerosi progetti che vanno oltre l’uso previsto dalla Apple. automaticamente in tutti i cellulari in cui è installata.
Per questa ragione, sul web si trovano numerosissime App scritte da • BuildAnApp (http://buildanapp.com); tra i servizi a pagamento
vari sviluppatori e rese disponibili qualcuna gratis e qualche altra, su è il più economico, sebbene, malgrado prometta di insegnarci a
negozi on-line che “spuntano come funghi”, pagando cifre peraltro creare una App sei semplici soli passi, l’accesso non sia sempre
abbastanza modeste. facile. Gli strumenti per creare le proprie App sono gratis; si
Apple e Google hanno però pensato di proporre kit di sviluppo per pagano 49 euro solo se vogliamo per mettere le nostre App
offrire agli utenti la possibilità di crearsi da soli le proprie App, sulla nell’Android Market e 149 per pubblicarle nell’iTunes di Apple.
base delle loro esigenze. La “mela” ha realizzato un kit di sviluppo • Magmito (www.magmito.com); permette di preparare App per
ad hoc scaricabile da iTunes, ma anche, cosa interessante per gli iOS, Android e BlackBerry, ma anche in Java, per Symbian e
utenti italiani che hanno poca dimestichezza con l’inglese, un corso Windows Mobile, quindi è estremamente completo. Prevede
di applicazioni per iOS in 12 lezioni realizzato all’Università di Pisa e la possibilità di accedere gratis, almeno per creare App non
che verte su linguaggio, interfacciamento e progettazione, tenuto da destinate al commercio ma alla condivisione tra gli utenti del
un esperto del CNR. Visto che la richiesta ha ampiamente superato i servizio e se si accetta di ospitare banner pubblicitari. Creare App
60 posti previsti, il Dipartimento di Informatica dell’università pisana che si desidera rivendere o senza accettare i banner, ha un costo
sta pensando di istituire un “master” proprio sul sistema iOS, rivolto di 99 euro per ciascuna.
a chi vuole imparare a creare App, oggi un vero e proprio lavoro che • Mobile Roadie (http://mobileroadie.com); è il servizio riservato ai
già rappresenta un business e che per il futuro promette un giro professionisti delle App per BlackBerry, iPhone, iPad e sistema
d’affari da sogno. operativo Android e l’accesso costa parecchio: da 1.200 euro
Anche Google ha realizzato e propone un proprio kit, chiamato App per la versione normale (Core) a qualcosa in più per la Plus,
Inventor, completamente gratuito: per accedervi basta crearsi un fino a 5.000 per la Pro. Il supporto che fornisce è all’altezza e
account Gmail. La realizzazione di App sul servizio di Google è molto le possibilità di personalizzazione delle App sono notevoli, Un
semplice e viene guidata passo-passo: basta entrare nella pagina po’ meno pregevole è la traduzione in Italiano realizzata dal
di benvenuto, assegnare un nome al proprio progetto e, dal lato supporto multilingue del sito. Essendo un servizio professionale
dello schermo, scegliere le opzioni che permettono di aggiungere non prevede account gratuiti per chi desidera creare App di
testi e animazioni ed altro ancora. Per inserire nell’App gli strumenti pubblico dominio.
disponibili, basta trascinarli nello schermo virtuale (che ricorda
quello dell’iPhone). Le operazioni di base non richiedono particolari
conoscenze e comunque l’ambiente rende disponibili, nella
sezione “learn”, vari suggerimenti.
Più complete sono le altre piattaforme specifiche disponibili
sul web, però quasi tutte a pagamento; tra esse vanno citate
Appdoit, Appsbuilder, BuildAnApp, Magmito e Mobile Roadie.
Vediamo le caratteristiche salienti di questi siti.

• Appdoit (www.appdoit.com); la pagina di avvio si divide in


aree tematiche e l’uso del servizio è intuitivo, grazie alla
struttura ad icone e a spiegazioni chiare. Il servizio si paga
99 euro nella versione più stringata e 249 in quella “full”
e comprende il diritto illimitato agli aggiornamenti. Gli
strumenti forniti consentono di sviluppare rapidamente App
per iPhone, iPad e Android.
• Appsbuilder (www.apps-builder.com); questo servizio ha
la home-page in italiano ed è quindi di più facile utilizzo per
chi ha poca familiarità con l’inglese. Per scrivere una App, una
volta definito il nome e la descrizione (che apparirà nel market
store da cui gli utenti potranno comperare le App realizzate) si
accede alla fase di creazione, dove si gestiscono i contenuti e
la grafica. Iscriversi al servizio costa 190 euro, cifra destinata a
salire se si desidera aggiungere un account AdMob con il quale
il sito propone banner di pubblicità degli sviluppatori iscritti. Il
sito prevede anche la possibilità di creare gratuitamente App

piacere con lo stesso nome ma con parametri Come potete vedere in tale listato, questa è
diversi. Per esplicare questo concetto, fac- proprio una particolarità; sarà infatti il com-
ciamo un esempio che usa il nostro pseudo- pilatore a decidere quale metodo utilizzare, a
linguaggio (Listato 8). seconda dei parametri che passeremo.

114 Maggio 2011 ~ Elettronica In


Corso di programmazione iPhone

classe figlio riscrive un metodo già espresso


Listato 9 - Override di un metodo e chiamata di un dalla sua classe padre. L’override è una delle
condizioni che si utilizzano di più in assoluto
metodo del padre in override, pseudo-linguaggio
quando si lavora in OOP, visto che il suo sco-
class Veicolo
po è permetterci di riscrivere completamente
{ un metodo oppure, come vedremo, esten-
void accelera() derne le funzionalità. Nel Listato 9 vediamo
{
//Implementazione del metodo accelara un esempio, fatto sempre tramite il nostro
} pseudo-linguaggio. In tale Listato abbiamo
}
aggiunto una parola chiave in più: “super”;
class Macchina extends Veicolo possiamo usarla nella classe figlio per chia-
{
void accelera()
mare un metodo oppure una proprietà della
{ classe padre e poterla riutilizzare all’interno di
//OVERRIDE del metodo della classe padre un metodo, in override o no.
//In questo contesto posso scrivere il metodologia
//del padre, la classe Veicolo A questo punto abbiamo terminato la nostra
} breve introduzione alla programmazione
void accelera(int aumento) OOP; non vi preoccupate se molti concetti non
{ vi saranno subito chiari, perché se non avete
super->accelera();
mai avuto alcuna esperienza orientata agli og-
//Override con chiamata del metodo del getti, non sarà immediato giocare con questo
//padre della classe paradigma e farlo proprio.
}
} Nella prossima puntata vedremo questi
concetti portati in objectiveC, la sintassi e
le possibilità offerte da questo linguaggio,
Questo tipo di funzionalità non è presente rimanendo però sempre nel contesto della
né in ObjectiveC, né in C; nel primo perché programmazione iPhone. Il mondo OOP è ve-
l’objectiveC è debolmente tipizzato, mentre ramente vasto e molto interessante, in questa
nel secondo per motivazioni prettamente sto- prima sezione abbiamo introdotto solo la base
riche. Prima di spiegare la differenza tra de- di questo paradigma, nei prossimi capitoli
bolmente e fortemente tipizzato, analizziamo fisseremo questi concetti e ci addentreremo
il concetto per l’override; come immaginerete, nei fondamenti del nostro linguaggio target,
il compito di questo è simile all’overload, ma ObjectiveC, dei design patterns che ci saranno
con la differenza che si verifica quando una utili per capire e sviluppare le nostre App. 

rduino
la piattaforma open source alla portata di tutti
STARTER KIT CON ARDUINO UNO
kit composto da scheda Arduino UNO, cavo USB,
mini Breadboard a 170 contatti con 10 cavetti
cod: da 15 cm, piastra sperimentale (58,50 x 82,70mm),
ARDUINOUNOKIT 2 motori elettrici, fotoresistenza, termistore, LED,

55,oo
micropulsanti, transistor e molti altri componenti


necessari per cominciare ad utilizzare
questa potente piattaforma hardware.
IVA inclusa.

Via Adige, 11 • 21013 Gallarate (VA) Maggiori informazioni su questo prodotto e su tutte le altre apparecchiature sono disponibili sul sito
Tel. 0331/799775 • Fax. 0331/792287 www.futurashop.it tramite il quale è anche possibile effettuare acquisti on-line.

Elettronica In ~ Maggio 2011 115


di WALTER DAL MUT e FRANCESCO FICILI
Corso di programmazione iPhone

Corso di programmazione
PUNTATA 2
iPhone

D opo la prima
puntata, intro-
duttiva, è giunto il
sviluppo è assolu-
tamente necessario
un computer Macin-
momento di vedere tosh basato su proces-
come avviene l’instal- sore Intel, altrimenti
lazione dell’ambiente non sarà possibile
di sviluppo X-Code, configurare la SDK.
che ci permetterà di
scrivere le nostre ap- Installazione
plicazioni aventi per di X-Code
target iPhone e iPad. Per installare X-Code
L’ambiente permette è necessario scaricare
inoltre il debugging, il sul Mac l’immagine
testing e tutto ciò che disco “dmg” diretta-
riguarda la gestione mente dal sito degli Installiamo ed impariamo ad
dei dispositivi dedica- sviluppatori Apple. In
ti allo sviluppo. Fig. 1 è rappresentata
utilizzare l’ambiente di sviluppo
È importante ricorda- la pagina web dedi- X-Code, grazie al quale possiamo
re che per installare cata al sistema iOS, scrivere, debuggare e testare le
XCode dedicato allo da dove è possibile applicazioni per iPhone e iPad.

Elettronica In ~ Giugno 2011 61


Corso di programmazione iPhone
Fig. 1 - Il sito Developer Apple.

scaricare la SDK; l’URL di questo sito è http:// su dispositivo; a questo punto della trattazione
developer.apple.com, nel caso in cui avessimo già basta una registrazione ridotta al solo account,
un account di sviluppo per altre piattaforme quindi senza oneri di spesa, in quanto per
Apple, potrà andare bene la firma già registra- iniziare è necessario solamente il simulatore
ta. I tools di sviluppo sono riservati ai soli tito- fornito nella SDK.
lari di account validi, per cui la registrazione è Come possiamo vedere in Fig. 3, nella sezione
obbligatoria; una volta completata la registra- dedicata agli sviluppatori possiamo leggere la
zione, si può accedere all’area riservata, dalla documentazione, scaricare le versioni di svi-
quale prelevare il pacchetto di Xcode, ovvero il luppo di iOS e molto altro ancora; lasciamo a
tool necessario al lavoro su iOS, sia per iPhone voi la scelta di approfondire la conoscenza del
che per iPad. Per iniziare la registrazione biso- portale apple-developers.
gna fare clic sul link in alto a destra, visibile già
nella Fig. 1, identificato dall’etichetta Member
Center. Una volta fatto clic, il sistema naviga
verso la sezione di login (come si può vedere
in Fig. 2) dedicata allo sviluppo. Nel caso in
cui non fossimo già detentori dell’account,
dobbiamo cliccare sul pulsante a destra della
finestra, dove è scritto “Need to register? Just
now”; una volta fatto questo, si apre un’altra
pagina da dove è possibile iniziare la registra-
zione. L’acquisto della licenza di sviluppo è
necessario per la sintesi di ogni nostro progetto Fig. 2 - Finestra di login.

62 Giugno 2011 ~ Elettronica In


Corso di programmazione iPhone

Fig. 3 - L’area riservata agli sviluppatori, da questa sezione possiamo scaricare Xcode.

L’installazione del pacchetto Xcode non richie- pulsante (“Getting started with Xcode”) è una
de alcuna configurazione ad-hoc ed è possibile guida introduttiva all’utilizzo di Xcode, una
farla senza problematiche di sorta, semplice- risorsa molto interessante che introduce i nuovi
mente facendo sul file un doppio clic e seguen- utenti all’utilizzo ed ai segreti di Xcode. Il terzo
do i passi dell’installer. pulsante, infine, ci collega tramite il browser
al sito di riferimento degli sviluppatori http://
Avviare X-Code developer.apple.com. Nella sezione di destra è
Ad installazione terminata, l’icona di Xcode presente una lista delle ultime applicazioni
non compare tra le applicazioni del computer, su cui avete lavorato: se è la prima volta che
ma viene inserita in un altro punto del nostro
file system; per questa motivazione bisogna in-
dividuarla tramite il finder del computer, come
mostrato nella Fig. 4. La chiave di ricerca più
proficua per questa operazione è “xcode.app”.
Una volta individuata l’icona del programma,
facciamo doppio-clic sull’icona rappresentante
il martello per avviare finalmente X-Code e
poter iniziare la nostra avventura nel mondo
iPhone. Nella Fig. 5 è rappresentata la finestra
di introduzione di Xcode, a sinistra della quale
è possibile vedere tre grossi pulsanti: il pri-
mo, chiamato “Create a new Xcode project”,
serve per creare un nuovo progetto; il secondo Fig. 4 - Cercare l’applicazione X-Code dopo aver effettuato l’installazione.

Elettronica In ~ Giugno 2011 63


Corso di programmazione iPhone
Fig. 5 - Intro di X-Code Fig. 6 - Navigazione delle risorse disponibili in Xcode.

installate Xcode, questa sarà vuota. In basso a


sinistra, infine, c’è il pulsante “Open Other...”
che serve ad aprire un progetto che non com- progetto; quindi facciamo clic su questo colle-
pare nel menu veloce sulla destra, in quanto gamento ed il sistema apre una seconda pagina
non è utilizzato di recente. dove possiamo scegliere dettagliatamente
Il pulsante che ci interessa di più è sicuramente quale applicazione vogliamo realizzare.
il primo, ossia “Create a new Xcode project”, in Nella Fig. 6 è rappresentata la schermata per la
quanto andremo subito a configurare un nuovo realizzazione di un App per iPhone; sulla sini-

Fig. 7 - InterfaceBuilder: lo strumento per la creazione delle grafiche.

64 Giugno 2011 ~ Elettronica In


Corso di programmazione iPhone

stra sono presentate due sezioni, la prima delle che siamo sempre di fronte Fig. 6 - Il simulatore iPhone.
quali riguarda effettivamente lo sviluppo iPho- ad un simulatore e non ad
ne sotto l’etichetta iOS, mentre la seconda, con un emulatore, quindi molte
la dicitura Mac OS X, è dedicata allo sviluppo caratteristiche risultano di-
di applicazioni per computer Mac. In questo verse rispetto al device fisico,
corso ci occuperemo solo della prima sezione specialmente i tempi di ese-
e, nella fattispecie, della parte Application, dato cuzione. Si pensi ad esempio
che svilupperemo applicazioni stand-alone ad un collegamento Internet,
e non ci occuperemo, per il momento, dello dove, a meno che non utiliz-
sviluppo di librerie. ziate una connessione GSM
Nel riquadro grande sono presenti sette dal vostro Mac, la velocità di
tipologie di modelli di App già pronte e di- download e parsing delle pa-
sponibili per lo sviluppo dei nostri progetti; in gine web è molto più elevata
basso, invece, si trova una descrizione di quello rispetto all’elaborazione sulla
che andremo a realizzare, differente per ogni CPU ARM a bordo dell’iPho-
modello applicativo. ne, specie nei modelli più
Tutti questi modelli sono disponibili sia per “anziani” come il 2G o il 3G.
iPhone che per iPad, a parte alcuni che sono
riservati ad uno solo dei due dispositivi, come Creazione di un progetto
la “Navigation Based Application” dedicata Xcode
solo a iPhone, “Split View-Based Application” Dalla schermata di selezione del template
dedicata solo ad iPad, “Utility Application” di Xcode, che abbiamo già visto nella Fig. 6,
solo per iPhone. selezioniamo la “View-based Application”.
Tipicamente, quando si ha una buona cono- Inseriamo il nome del nuovo progetto (possia-
scenza del sistema ci si dedica quasi esclusi- mo cominciare con il classico Hello World) e
vamente alla “Window-based Application”, proseguiamo. Una volta fatto ciò, si apre una
in quanto è l’unica che permette un template nuova finestra visibile nella Fig. 9. La finestra
universale, ovvero un singolo progetto per di Xcode 4, ovvero l’ultimo nato in casa Apple,
un’applicazione sia iPhone che iPad. è divisa in due sezioni per la scrittura del co-
Xcode non è l’unico tool di sviluppo che ci è dice sorgente ed in tre per quello che riguarda
stato messo a disposizione dalla Apple: un l’integrazione di Interface Builder, necessario
altro prezioso IDE che utilizzeremo per la allo sviluppo della grafica. Nell’area a sinistra
creazione delle nostre App è InterfaceBuilder, dell’IDE è presente il project manager, e nella
scopo del quale è semplificarci la vita nella parte centrale trovate l’editor dove scrivere il
creazione delle nostre “viste”, ovvero la parte nostro codice.
grafica della nostra applicazione, come mostra Ma prima di addentrarci nel mondo iPhone
la Fig. 7. L’ultimo programma a nostra dispo- dobbiamo fare una digressione sul linguaggio
sizione è il simulatore, visibile in Fig. 8. Questo ObjectiveC, per fissare i concetti espressi nella
prezioso strumento di sviluppo permette la prima lezione utilizzando la giusta sintassi.
simulazione delle nostre applicazioni senza
obbligatoriamente sintetizzarle su un dispo- Il linguaggio ObjectiveC
sitivo fisico; con esso possiamo simulare un L’objectiveC, come in tutti i linguaggi di pro-
iPhone avente a bordo diverse versioni del grammazione, necessita di un “entry-point”,
sistema operativo o anche l’iPad, anche questo ovvero un punto da dove la nostra applica-
con diverse versioni dell’OS. Per ogni dispo- zione inizierà ad eseguire il suo codice. Nel
sitivo possiamo simulare alcune condizioni di caso dell’objective, questo entry point si trova
lavoro, come una telefonata in arrivo oppure all’interno del file chiamato main.m, presente
un problema di memoria, ruotare il dispositi- nella cartella Other Sources, all’interno delle
vo, stoppare e riavviare l’applicazione, esegui- risorse di progetto.
re uno shake ed altro ancora. Ricordiamo, però, Una prima differenza essenziale con il C è

Elettronica In ~ Giugno 2011 65


Corso di programmazione iPhone
Fig. 9 - Main window Xcode.

l’estensione del file: l’estensione “.m” (main.m), file, infatti, come notiamo, questo ha come
indica al compilatore che il codice è di tipo estensione “.h”.
ObjectiveC e quindi dovrà essere trattato con La direttiva “import” dell’objectiveC è decisa-
le dovute considerazioni. All’interno di questo mente più efficiente della sua controparte in C,
file troviamo subito un primo assaggio di cioè la direttiva “include”, che serve a importa-
ObjectiveC. re nel file corrente delle definizioni. Infatti in C,
Prima di analizzare il codice ed iniziare a per evitare il problema delle definizioni multi-
capirne i fondamenti, analizziamo la struttura ple, è necessario introdurre opportune direttive
del file, aiutandoci con il Listato 1. È importan- del preprocessore, che condizionano il proces-
te sottolineare che per ObjectiveC, come per il so di compilazione in modo da prevenire errori
C, è assolutamente necessaria la dichiarazione o sviste dello sviluppatore.
esplicita dei “prototipi”, o meglio delle firme Nel Listato 2 è riportato un esempio di file
dei metodi per tutto quello che vogliamo uti- header in C; le direttive “ifndef” ed “endif” che
lizzare nel codice. Per fare questo si creano due trovate in esso sono “di compilazione condi-
file per ogni risorsa da aggiungere: uno di inte- zionale”: in pratica eseguono una direttiva di
stazione chiamato “header” che ha estensione
“.h”, ed un secondo che invece implementa
realmente le dichiarazioni espresse nel “hea- Listato 1 - Introduzione ai files objectiveC.
der”, avente estensione “.c” per il linguaggio C
#import <UIKit/UIKit.h>
ed “.m” per l’ObjectiveC.
Ritornando al Listato 1, vediamo sulla prima int main(int argc, char *argv[]) {
… //Codice objective
riga la prima direttiva del preprocessore: la }
chiave “import” serve per includere un altro

66 Giugno 2011 ~ Elettronica In


Corso di programmazione iPhone

controllo su una costante, che nel nostro caso


si chiama “_ _ ESEMPIO_H_ _”. Se questa non Listato 3 - Corpo della funzione main.c.
esiste, la si crea tramite la direttiva “define” e
poi viene processato anche il contenuto, quindi NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]
init];
tramite questo metodo anche se provassimo int retVal = UIApplication(argc, argv, nil, nil);
ad includere tante volte questo file “h”, non [pool release];
return retVal;
si verificherebbero problemi di compilazione,
visto che dopo la prima volta il file verrebbe
scartato dal nostro compilatore in quanto già è possibile vedere nella riga 1 del Listato 3, ab-
processato. biamo una variabile puntatore di tipo “NSAu-
In objectiveC non è necessario utilizzare tale toreleasePool”.
tipo di sintassi, perché infatti possiamo utiliz- Il fatto che la variabile sia un puntatore si nota
zare la direttiva del preprocessore “#import” dalla presenza dell’asterisco prima del nome
ed essa si occuperà di risolvere il problema della variabile “pool”, esattamente come in C.
della multi-inclusione. Con l’istruzione NSAutoreleasePool *pool si
Ritorniamo al nostro codice del Listato 1, vuole dichiarare quindi una variabile che sarà
alla seconda riga del quale troviamo il tipi- di tipo “NSAutoreleasePool”. Un altro esempio
co “entry-point” C, con i due parametri per potrebbe essere NSString *stringa, che identifica
ottenere informazioni aggiuntive che potreb- una variabile di nome “stringa” di tipo “NS-
bero arrivare dalla console che avvia il nostro String”. L’istruzione successiva è [[NSAutore-
programma. Per chi non avesse mai visto la leasePool alloc] init]: questa espressione si può
struttura proposta alla riga 2, nella variabile scomporre in due parti, una prima [NSAuto-
“argc” sono indicati il numero di parametri releasePool alloc] ed una seconda [pool init]. Le
passati al nostro applicativo, mentre la varia- parentesi quadre in ObjectiveC sono il modo
bile “argv” è un puntatore ad un vettore di sintattico con cui si invocano i metodi sugli
caratteri, quindi un puntatore di puntatore, che oggetti. Il tipo NSAutoreleasePool è quindi
contiene le stringhe passate dalla console verso il nostro primo oggetto in ObjectiveC; non lo
la nostra applicazione. abbiamo scritto noi ma ora sappiamo che è un
Un esempio pratico si può fare quando passia- oggetto. Il metodo “alloc” non è propriamen-
mo diversi parametri ad un programma di tipo te un costruttore (come quelli descritti nella
“salutami -name elettronicain -lingua inglese”, prima puntata), perché serve solo per allocare
dove salutami è il nome del programma, la in memoria per un certo tipo di oggetto. Il me-
variabile argc avrà valore 5, mentre la varia- todo “alloc” è un parente stretto della “malloc”
bile argv sarà costituita da un array di cinque del C; con questa procedura abbiamo creato
elementi ognuno dei quali rappresenta una fisicamente l’oggetto, ma non l’abbiamo ancora
stringa: “salutami”, “-name”, “elettronicain”, inizializzato (operazione che un costruttore di
“-lingua” ed “inglese”. un linguaggio OOP farebbe automaticamente).
Passiamo adesso ad analizzare il Listato 3, Per inizializzarlo correttamente utilizzeremo il
che integra il Listato 1 aggiungendo la parte metodo “init”.
mancante di codice della funzione main. Come Nella seconda riga, invece, è presente una linea
di codice C (int retVal = UIApplication(argc,
argv, nil, nil)); con essa stiamo richiamando una
Listato 2 - Esempio di dichiarazione di un file header C. funzione UIApplication(...) con i parametri ne-
cessari ed il suo valore di ritorno di tipo intero,
//esempio.h
#ifndef __ESEMPIO_H__ assegnando questo valore alla variable retVal.
#define __ESEMPIO_H__ Questa funzione è definita all’interno del
void saluta(void);
framework “Foundation” di cocoa touch e serve
int testFunction(char *string); per inizializzare e lanciare l’applicazione. Alla
riga 3 stiamo invece chiamando un metodo su
#endif
un oggetto, infatti sono presenti le parentesi

Elettronica In ~ Giugno 2011 67


Corso di programmazione iPhone
Questo metodo ci fornisce una maggiore sicu-
Listato 4 - Esempio di prenotazione e successivamente rezza, a patto di rilasciare sempre i riferimenti
liberazione della memoria. agli oggetti quando abbiamo terminato di uti-
lizzarli, altrimenti questi resteranno sempre in
NSObject *stringa = [[NSObject alloc] init];
memoria causando un problema di “memory
//A questo punto il reference counter è diventato 1, leakage”. Per capire questo concetto facciamo
//questo è gestito dalla creazione dell’oggetto. un esempio pratico: in objectiveC, per aumen-
[stringa retain];
//Ora il reference counter è 2 tare il numero di riferimenti si deve utilizzare il
[stringa retain]; metodo “retain”, mentre per ridurre il conteg-
//Reference Counter = 3
[stringa release]; gio si usa il metodo “release”. Durante i nostri
//Reference Counter = 2 esempi non utilizzeremo molto il metodo
//L’oggetto non va via dalla memoria, esistono anco-
ra 2 riferimenti.
“retain”, in quanto esistono metodologie che
[stringa release]; invocano per noi questo metodo, mentre fare-
//Reference counter è 1 mo un largo uso del metodo “release”.
[stringa release];
//Referece counter zero ora viene rimosso dalla me- Nel Listato 4 abbiamo fatto uso di un oggetto
moria di nome “NSObject” per due motivazioni: la
prima è che attualmente non abbiamo ancora
quadre e l’oggetto NSAutoreleasePool che abbia- scritto il nostro primo oggetto; la seconda è che
mo dichiarato in precedenza. Il metodo release vogliamo sollevare una questione riguardante
è il parente della free del C e possiamo dire, lo spazio dei nomi di un’applicazione. Il pro-
per adesso, che serve a liberare la memoria di blema che viene introdotto è molto noto e si ri-
lavoro (vedremo la gestione della memoria solve con i “namespaces”, ovvero lo spazio dei
più nel dettaglio, nel successivo paragrafo). nomi, un modo, questo, per evitare di creare
Sull’ultima riga del Listato 3 restituiamo al si- classi o funzioni con lo stesso nome, il che ren-
stema operativo il codice di uscita della nostra derebbe impossibile la compilazione in quanto
applicazione allo stesso modo del C. abbiamo detto che l’ObjectiveC non ammette
“overload” dei metodi ed il C non lo ammette
Gestione della memoria per iPhone per le funzioni. In aggiunta, non si possono
Nella prima puntata abbiamo già detto che per avere classi con nomi identici, altrimenti il
iPhone è necessaria la gestione della memo- compilatore non saprebbe quale utilizzare. Per
ria da parte del programmatore; questo si fa risolvere questo problema in ObjectiveC, così
su tutti gli oggetti tramite il metodo release, come nei linguaggi che non hanno un sistema
il nostro pseudo-distruttore. Nel C, quando “namespace” ufficiale, si introduce un prefisso
chiamiamo la funzione “free” su un tipo di prima del nome come prefisso della classe.
dato, questo viene immediatamente rimosso Questa soluzione è utilizzata dalla Apple
dalla memoria. Qualunque altro puntatore che stessa, infatti nel nome “NSAutoreleasePool” il
mantiene il riferimento con questa porzione di prefisso NS è lo spazio di nomi scelto: infatti è
memoria liberata, nel momento in cui tenterà l’abbreviazione di NextStep (quando Steve Jobs
di fare una qualunque operazione di “read” uscì dalla Apple nel 1985, fondò una società
o “write” manderà in crash l’applicazione, in chiamata proprio Next, che sviluppò un siste-
quanto cercherà di fare riferimento ad una por- ma operativo chiamato NextStep che in seguito
zione di memoria che non appartiene più allo
spazio dell’applicazione. In ObjectiveC que-
sto problema è stato risolto, dato che quando Listato 5 - Costrutto fondamentale if-else.
invochiamo il metodo “release” su un oggetto,
questo non viene immediatamente rimosso if (1 == 1) {
dalla memoria, ma si diminuisce un “referen- printf(“Sono uguali”);
} else {
ce counter” e solo quando questo numero si printf(“Sono diversi”);
riduce a zero, l’oggetto viene effettivamente }
rimosso dalla memoria.

68 Giugno 2011 ~ Elettronica In


Corso di programmazione iPhone

infatti ci sono i vettori di caratteri e quindi vale


Listato 6 - Costrutto fondamentale while. lo stesso discorso anche per ObjectiveC; però la
Apple ha messo a nostra disposizione la classe
while(i < 5)
NSString, semplificandoci notevolmente la
{ vita. Vediamo subito un esempio di una stringa
printf(“%d”, i); costante:
++i;
}
NSString *stringa = @”Io sono un oggetto”;

divenne la base di quello che è l’attuale sistema Notiamo che, a differenza del C, prima dei
operativo utilizzato dalla Apple, MacOS X). doppi apici c’è il simbolo speciale “@”, che
Vi consigliamo di utilizzare sempre un vostro serve proprio a indicare che è un riferimento
spazio nomi, per non incorrere in problemi ad un oggetto; infatti, come possiamo vedere,
con codici Apple o comunque di terzi parti. In stiamo dichiarando un puntatore a oggetto
questo corso utilizzeremo il prefisso EI come “NSString”. Quando utilizziamo la classe “NS-
contrazione di Elettronica In. String” dobbiamo fare attenzione, perché essa è
una classe immutabile. Il termine “immutabile”
Iniziare a lavorare in ObjectiveC indica che tale classe non può essere modifica-
Per scrivere realmente un po’ di codice Objec- ta, in quanto è sintetizzata come un vettore di
tiveC, dobbiamo ancora vedere i costrutti base caratteri e non è più possibile scegliere di au-
del linguaggio, che sono essenzialmente quelli mentare o ridurre lo spazio una volta che tale
del C, e le strutture dati base che vengono for- vettore è stato allocato. Per questa motivazione,
nite direttamente dalla Apple. se stiamo lavorando con stringhe mutabili, pos-
Iniziamo comunque con la base di ObjectiveC, siamo utilizzare la classe NSMutableString, che
in modo da poter poi realizzare un’applicazio- permette di modificare la struttura delle stringa
ne reale. I costrutti base if, for, while, sono esat- riducendo i problemi di memoria, in quanto le
tamente quelli del C, con in più la possibilità stringhe non vengono continuamente rialloca-
di dichiarare le variabili direttamente nei cicli. te. Anche per gli array abbiamo delle classi già
Una particolarità dell’Objective C è che non è pronte all’uso (NSArray, NSMutableArray, NS-
utilizzato il “NULL” bensì il “nil”. Set, NSMutableSet) che permettono di registra-
Nel Listato 5 vediamo il costrutto “if”, che, re al loro interno i nostri oggetti. Nel Listato 8
come possiamo vedere, è lo stesso del C.
Nell’esempio specifico viene controllata l’ugua-
glianza delle espressioni. I costrutti while e do/ Listato 7 - Costrutto fondamentale for.
while sono sempre quelli del C. Nel Listato 6
vediamo un esempio di uso del while. Il co-
for(int i=0; i<10; i++)
strutto for, il cui esempio applicativo è visibile
{
nel Listato 7, è l’unico che oltre a mantenere
printf(“%d”, i);
l’eguaglianza con il C permette anche soluzioni
}
di scorrimento diverse; analizzeremo queste ul-
time quando e se sarà necessario. Comunque è
sempre possibile utilizzare il metodo standard
C. In questo esempio è stata dichiarata la Listato 8 - Esempio completo in ObjectiveC.
variabile “i” all’interno del “for”; fate atten-
zione a questa dichiarazione, in quanto non for (int i=0; i<[lista count]; i++) {
è ANSI C ma è possibile utilizzarla in Objec- NSLog(
@”Indice: %d - Valore: %@”,
tiveC senza alcun problema. I tipi base del C i,
sono stati ridichiarati in ObjectiveC, anche se [lista objectAtIndex: i]
);
è sempre possibile utilizzare quelli standard. }
Come ricorderete, in C le stringhe non esistono,

Elettronica In ~ Giugno 2011 69


Corso di programmazione iPhone
posizione corrente della lista.
Listato 9 - Primo esempio reale su Iphone. La struttura di NSLog è la
seguente: NSLog(NSString *,
#import <UIKit/UIKit.h> …) dove i dots indicano un
#import “helloworldViewController.h”
numero variabile di parame-
int main(int argc, char *argv[]) { tri. La prima parte deve esse-
NSString *stringa = @”Io sono un oggetto”;
re una stringa e quindi deve
NSArray *lista = [[NSArray alloc] initWithObjects: stringa, nil]; iniziare con il carattere “@”,
for ( int i=0; i<[lista count]; i++) {
in quanto è un puntatore, e
NSLog(@”Indice: %d - Valore: %@”, poi un numero variabile di
i, parametri come descritto in
[lista objectAtIndex: i]
); precedenza. Il contenuto del
} primo parametro è: “Indice:
%d - Valore: %@”. Il primo
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; tipo che vogliamo rappre-
int retVal = UIApplicationMain(argc, argv, nil, nil); sentare è un normale nu-
[pool release];
return retVal; mero decimale (%d) mentre
} il secondo (%@) indica che
vogliamo rappresentare un
possiamo vedere un primo esempio completo oggetto come se fosse una stringa. Prendiamo
in ObjectiveC. Prima di tutto abbiamo creato adesso il nostro progetto “HelloWorld”, che
una stringa, che è NSString *stringa = @”Io sono utilizzeremo ancora nella prossima puntata,
un oggetto”. Dopo creiamo un array di elementi apriamo il file “main.m” posto sotto il gruppo
chiamato lista. chiamato “Other Sources” e scriviamo al suo
Come abbiamo già spiegato, dobbiamo allocare interno la stringa NSString *stringa = @”Io
lo spazio in memoria di tipo “NSArray” trami- sono un oggetto”. Il file “main.m” dovrebbe
te la direttiva “[NSArray alloc]” e poi chia- apparire come il Listato 9. Per eseguire questo
miamo il nostro costrutture “initWithObjects”. codice dobbiamo fare clic sul pulsante Run in
Questo costruttore necessita di una serie di alto a sinistra nella barra di controllo dell’IDE,
oggetti separati da virgola e conclusi con il come visibile in Fig. 10. Questa operazione
terminatore “nil”. Dopo aver allocato l’array, effettuerà la compilazione ed avvierà la console
o meglio un oggetto “NSArray” che contie- nella quale potremmo visualizzare i messaggi
ne l’array reale, cicliamo gli elementi al suo stampati dalla funzione NSLog. Il risultato di
interno tramite il costrutto for. In questa dichia- questa operazione è visibile in Fig. 11.
razione stiamo invocando il metodo “count” Dopo aver visto il messaggio possiamo chiu-
sull’oggetto “lista”, che restituisce il numero di dere il simulatore facendo la combinazione
elementi registrati: in questo caso, solo uno. MELA+Q. Per questa lezione abbiamo termi-
Per ogni elemento nella lista utilizziamo la fun- nato, nella prossima vedremo i concetti del
zione NSLog, che scrive nella console iPhone framework MVC (Model View Controller)
un nostro messaggio, contenente l’indice ed pesantemente utilizzato nello sviluppo delle
il valore dell’elemento immagazzinato nella applicazioni per iPhone. 

Fig. 10 - Barra di controllo


di Xcode.

Fig. 10 - La console Xcode


dopo che abbiamo avviato
la nostra applicazione.

70 Giugno 2011 ~ Elettronica In


di WALTER DAL MUT e FRANCESCO FICILI
Corso di programmazione iPhone

Corso di programmazione
PUNTATA 3
iPhone

È giunto il momen-
to di introdurre
il discorso sui Design
e nelle librerie che
utilizzeremo. Nella
seconda parte di que-
Patterns; in questa sta puntata, proporre-
puntata del corso mo due applicazioni,
spiegheremo cosa una prima molto
sono e come usarli e, semplice (il classico
in particolare, lavore- Hello World) ed una
remo su due di essi: seconda leggermente
un primo strutturale più complessa, dove
di nome M.V.C. (Mo- faremo agire il nostro
del View Controller), codice con la grafica. In questa terza
che è la struttura
utilizzata in “cocoa Design Patterns
puntata conosciamo
touch” (il framework I design patterns i Design Patterns,
per sviluppare su sono delle guide lines imparando ad usare
iOS) ed un secondo, definite dalla “Gang due di essi: Model
chiamato “Single- of Four”, un gruppo
ton”, che viene molto di quattro program- View Controller e
utilizzato nei progetti matori che hanno Singleton.

Elettronica In ~ Luglio / Agosto 2011 111


Corso di programmazione iPhone
Fig. 1 - Diagramma a blocchi del pattern M.V.C. chiedendo al Model i dati necessari al perse-
guimento del suo scopo; infine darà alla vista il
risultato dell’operazione.
Come potete immaginare, il codice scritto con
questo criterio è realmente ordinato e flessibile,
in quanto se vogliamo modificare la parte gra-
fica accederemo alla View, mentre se cambia
la base dati agiremo sul modello; infine, se vo-
gliamo cambiare la logica costruttiva, andremo
ad intervenire sul controller.
formalizzato e definito molte strutture tipica-
mente utilizzate durante lo sviluppo orientato Singleton Design Pattern
agli oggetti. I design patterns sono raggruppati Immaginiamo il dispositivo fisico iPhone: esso
in tre macro-categorie: strutturali, creazionali e incorpora dei componenti come l’accelero-
comportamentali. Per ognuna di queste cate- metro, la bussola digitale e altro ancora, che
gorie vi sono diversi schemi atti a risolvere i devono essere necessariamente riconosciuti
problemi classici dello sviluppo. Per i nostri dall’applicazione come tali. Emerge quindi la
scopi vedremo il pattern strutturale M.V.C. necessità di un design pattern che permetta di
ed il pattern creazionale Singleton. Il primo è modellare questi componenti come unici, in
forse la struttura più utilizzata nel mondo per modo da poterli utilizzare all’interno dell’ap-
lo sviluppo di un progetto, mentre il secondo plicazione senza riallocare continuamente
serve per creare un’istanza di un oggetto che nuovi oggetti.
sia unica per tutta la nostra applicazione. Il problema di creare una sola istanza di un
oggetto potrebbe sembrare semplice, ma invece
Model View Controller (M.V.C.) non è così, in quanto le classi statiche non aiu-
Il pattern strutturale M.V.C. si basa sulla crea- tano completamente nella risoluzione di questo
zione di tre componenti chiave: problema, dal momento che non mantengono
• Model; contiene tutti i modelli delle struttu- lo stato che invece è necessario ad un oggetto.
re dati utilizzate nell’applicazione; Per spiegare questo concetto dobbiamo prima
• View; realizza tutte le parti grafiche dell’ap- capire cosa si intende per classe statica.
plicazione; Come possiamo vedere nel Listato 1, abbiamo
• Controller: a questo componente è affidata una stringa di nome “condivisa” ed un metodo
tutta la gestione del collegamento tra dati e “getCondivisa” entrambi con la parola chiave
la parte visuale (quindi il collegamento tra “static”; ciò ci indica che entrambi sono statici,
Model e View). ovvero che esistono sempre ed a prescindere
dal fatto che esista o no l’oggetto “Esempio”.
In Fig. 1 è rappresentato lo schema a blocchi Infatti, grazie al prefisso static possiamo acce-
semplificato del pattern M.V.C.; in essa ve- dere a questa proprietà anche senza dover allo-
diamo che il componente centrale Controller care l’oggetto di tipo “Esempio”. Notate anche
chiede e riceve dal Model i
dati necessari all’elaborazio-
ne e trasmette alla View le Listato 1 - Classe con proprietà statica e metodo statico – pseudo linguaggio.
informazioni da visualizzare.
class Esempio
La view raccoglie le informa- {
zioni dell’utente e comunica static string condivisa;
al controller che deve essere static string getCondivisa()
effettuata un’azione. In fun- {
return self::condivisa;
zione dei dati ricevuti dalla }
View, il Controller eseguirà }
le richieste, eventualmente

112 Luglio / Agosto 2011 ~ Elettronica In


Corso di programmazione iPhone

la parola chiave “self” al posto di


“this”, in quanto ci si deve riferire Listato 2 - Esempio di classe Singleton – pseudo linguaggio.
alla classe e non ad una particolare
class Accelerometro
istanza. {
Come vediamo nella seguente riga //Proprietà statica della classe dello stesso tipo!
//L’oggetto incapsula se stesso tramite la proprietà
di codice: //statica.
static Accelerometro accelerometro = nil;
printf(“%s”, float x;
float y;
Esempio::getCondivisa()); float z;

//Restituisco l’istanza accelerometro


possiamo quindi chiamare in static Accelerometro getAccelerometro()
qualunque momento il metodo di {
if (self::accelerometro == nil) {
classe “getCondivisa” proprio per- self::accelerometro = new Accelerometro();
ché è stato dichiarato statico (esiste }
sempre). È importante sottolineare
return self::accelerometro;
che la classe può contenere metodi }
e proprietà relativi ad un’istanza e
float getX()
che questi ultimi possono utilizzare {
le proprietà e i metodi statici, però return this->x;
}
non è possibile fare il contrario,
cioè utilizzare proprietà e metodi //Altri metodi normali di istanza.
non statici da un metodo statico; }

ciò perché proprietà e metodi non


statici non esistono sempre, ma per avere la Vedremo un’implementazione ObjectiveC di
consistenza deve prima essere allocato l’ogget- questo design pattern quando realizzeremo le
to cui si riferiscono. nostre prime configurazioni.
Il pattern Singleton si occupa di creare un
oggetto normale rendendo disponibile all’ap- HelloWorld
plicazione solo ed esclusivamente una sua Per prima cosa ripren-
istanza, il che rende unico l’oggetto stesso. diamo il nostro primo
Pensiamo all’accelerometro: l’IPhone ne ha uno esempio realizzato
solo e viene modellato come un oggetto di tipo nella scorsa puntata
“Accelerometro”, però non possiamo crearne ed analizziamo i file al
uno nuovo ogni volta, altrimenti ogni istanza suo interno, che vedia-
avrebbe le sue proprietà. Perciò ne dobbiamo mo nella Fig. 2.
avere uno solo per tutte le applicazioni. Il progetto è diviso in
Come possiamo vedere nel Listato 2, abbia- quattro cartelle:
mo una proprietà statica, quindi condivisa, • Classes;
ed un metodo statico “getAccelerometro” che • Other Sources;
ritorna la singola istanza dell’accelerometro; • Resources;
nel metodo in analisi vediamo che facciamo • Frameworks.
un controllo sulla variabile “accelerometro”: se
questa è “nil” deve essere allocato l’oggetto e In “Classes” passere-
viene creato, mentre se invece esiste già, viene mo la maggior parte
direttamente restituito. del tempo del nostro
Grazie a questa struttura, siccome la pro- sviluppo, in quanto è
prietà accelerometro è statica e noi la ri- il punto dove met-
chiediamo sempre tramite il metodo statico teremo i Controllers
“getAccelerometro”, siamo sicuri che la classe e i Models. “Other Fig. 2 -Vista del
“Accelerometro” esista una sola volta. Sources” è la cartella project-manager di Xcode.

Elettronica In ~ Luglio / Agosto 2011 113


Corso di programmazione iPhone
iniziale dove si trova
il “main” dell’appli- Listato 3 - HelloWorldAppDelegate.h dichiarazione della classe HelloWorldAppDelegate.
cazione. “Resources”
//
è la directory delle // HelloWorldAppDelegate.h
risorse ed al suo // HelloWorld
//
interno metteremo le // Created by Elettronica IN on 04/12/10.
immagini che voglia- // Copyright 2010 Elettronica IN. All rights reserved.
mo utilizzare nella //

nostra applicazione #import <UIKit/UIKit.h>


e le viste che creia-
@class HelloWorldViewController;
mo tramite Interface
Builder. Infine, la car- @interface HelloWorldAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
tella dei “Framewor- HelloWorldViewController *viewController;
ks” contiene tutte le }
librerie che vogliamo
@property (nonatomic, retain) IBOutlet UIWindow *window;
utilizzare all’interno @property (nonatomic, retain) IBOutlet HelloWorldViewController *viewController;
della nostra applica-
@end
zione. Ad esempio,
quando ci dedichere-
mo alla geo-localizzazione dovremo aggiunge- dell’applicazione si intende l’entry point che
re il framework “MapKit”, che ci permetterà di viene utilizzato dal framework Cocoa Touch,
integrare le funzioni di libreria necessarie alla mentre il secondo file (HelloWorldViewCon-
creazione di applicazioni con le mappe. troller) è il Controller del pattern M.V.C.
Sempre riferendoci alla Fig. 2, vediamo il con- (spiegato nella parte iniziale di questa puntata)
tenuto della cartella “Classes”: al suo interno che viene generato automaticamente in quan-
sono presenti due file “.m” e due file “.h”, to abbiamo richiesto di creare un progetto di
perché per ogni file che creiamo esiste la sua tipo “View Based Application” (Applicazione
dichiarazione (il file “h”) e la sua implementa- basata su una vista).
zione (file “m”). Se avessimo scelto un altro tipo di template
Nel nostro esempio, uno dei due file si chiama avremmo avuto più o meno file a seconda di
“HelloWorldAppDelegate” ovvero il delega- quanto selezionato.
to dell’applicazione, mentre l’altro si chiama Da questo punto in avanti abbandoneremo
“HelloWorldViewController”. Per delegato completamente lo pseudo-linguaggio semplifi-

Listato 4 - Inizio del file HelloWorldAppDelegate.m.


#import “HelloWorldAppDelegate.h”
#import “HelloWorldViewController.h”

@implementation HelloWorldAppDelegate

@synthesize window;
@synthesize viewController;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

// Override point for customization after application launch.

// Add the view controller’s view to the window and display.


[self.window addSubview:viewController.view];
[self.window makeKeyAndVisible];

return YES;
}

114 Luglio / Agosto 2011 ~ Elettronica In


Corso di programmazione iPhone

Fig. 3 - Aprire la documentazione Apple.

cativo ed analizzeremo il codice scritto diretta-


mente in ObjectiveC.
Nel Listato 3 abbiamo la dichiarazione della
classe HelloWorldAppDelegate. Alla riga 1
abbiamo la direttiva “import” che include la metodi di tipo “setWindow” e “setViewCon-
libreria “UIKit”, la quale contiene tutte le com- troller” e altri due di tipo getWindow e get-
ponenti fondamentali per lo sviluppo iPhone. ViewController.
Essa sarà sempre presente in tutti i file. La riga porta diverse informazioni: la parola
La seconda riga si presenta già criptica: la di- “nonatomic” si riferisce al contesto di multith-
chiarazione “@class” indica al compilatore che read (che non vedremo in questo corso, quindi
viene utilizzata all’interno di “HelloWorldAp- lo prenderemo come dogma) mentre la secon-
pDelegate” una classe chiamata “HelloWorld- da, “retain”, significa che quando facciamo una
ViewController”. Tuttavia è importante notare get sulla proprietà in questione verrà chiama-
che la sua inclusione (import) viene fatta nel to sempre il metodo “retain” in automatico,
file .m legato a questa intestazione. ovvero verrà incrementato il reference counter.
La riga successiva è la dichiarazione del- Per liberare la memoria dobbiamo ricordarci
la classe: la direttiva “@interface” indica sempre di chiamare in modo corretto le release.
che stiamo dichiarando una classe di nome La parte finale di questa riga contiene una
“HelloWorldAppDelegate”. Successivamen- parola magica: “IBOutlet”. La parola chiave in
te troviamo questo frammento di codice “: questione non ha un senso programmatico, ma
NSObject”, che sta a significare che questa serve solo per collegare tale proprietà al tool
classe (HelloWorldAppDelegate) estende la “Interface Builder”; questo la deve considera-
classe base “NSObject”. Dopo, abbiamo la re come una Outlet (ovvero un componente
stringa “<UIApplicationDelegate>” ad indicare grafico).
che questa classe implementa un’interfaccia Successivamente viene indicata la proprietà
chiamata “UIApplicationDelegate”. come descritta nel corpo della dichiarazione.
Successivamente, nel corpo della dichiarazione Tutte le dichiarazioni della classe terminano
troviamo le proprietà della classe HelloWorl- con la parola chiave “@end”, che identifica
dAppDelegate: una di nome “window” di realmente la chiusura della classe.
tipo “UIWindow” ed una seconda di nome Vediamo ora come viene realizzato l’applica-
“viewController” di tipo “HelloWorld- tion delegate; apriamo quindi il file “HelloWo
ViewController”. rldApplicationDelegate.m”. La sua struttura è
Dopo il corpo della dichiarazione abbiamo abbastanza complessa, come possiamo vedere
una struttura particolare identificata dalle nel Listato 4, quindi la esamineremo per parti
parole chiave “@property”, che è una partico- iniziando con la testa del file. Il file inizia con
larità dell’ObjectiveC: in pratica dentro questa le due direttive del pre-processore “#import”,
dichiarazione stiamo indicando al compilatore che servono ad includere i file esterni. Il primo
che dovrà generare lui al posto nostro i “setter” indica il file di intestazione di questa classe ed
ed i “getter” delle proprietà, liberandoci da tale il secondo serve per specificare dove si trova la
onere. In pratica è come se avessimo creato due classe indicata, nel file header, con l’espressio-

Elettronica In ~ Luglio / Agosto 2011 115


Corso di programmazione iPhone
Fig. 4 - Posizionare la label nella vista iPhone.

ne “@class”. La terza riga inizia con la dichiara- Se vogliamo vedere la documentazione legata
zione “@implementation”, la quale indica che a questo protocollo (interfaccia) possiamo farlo
stiamo implementando una classe (in questo con ALT+doppio clic sul nome dell’interfaccia
caso si tratta di “HelloWorldAppDelegate”). che troviamo nel file .h, come mostra la Fig. 3.
Le due direttive “@synthesize”, che troviamo Se facciamo clic sull’immagine in alto a destra
successivamente, creano i setter ed i getter del box, possiamo navigare nella documen-
impostati dalle “@property” del file .h. tazione fornitaci direttamente dalla Apple, i
In un tipico file ObjectiveC, dopo le direttive contenuti della quale sono estremamente utili e
“@synthesize” si trovano le implementazioni completi.
dei metodi; infatti nel Listato 4 troviamo il Nel Listato 5 vediamo come viene implementa-
metodo “application”. to il metodo.
Qui la domanda sorge spontanea: come mai Il simbolo “-” indica che si tratta di un metodo
non sono dichiarati nel file “.h” della nostra di istanza e non statico (come spiegato durante
classe? La risposta è molto semplice: come la digressione sul Design Pattern Singleton),
possiamo vedere, la nostra classe implementa per differenziarlo da un metodo statico, che
un’interfaccia (UIApplicationDelegate), quindi, invece è preceduto dal “+”.
come visto nella precedente puntata, dobbiamo
implementare i metodi descritti dalla sua di-
chiarazione. In ObjectiveC, a differenza di altri Listato 5 - Implementazione del metodo Application
linguaggi, i metodi delle interfacce possono
anche essere opzionali e quindi lo sviluppatore – (BOOL)application:(UIApplication *)appli-
cation didFinishLaunchingWithOptions:(NSDictionary
non è obbligato ad implementare le interfacce, *)launchOptions
ma possiamo considerarle fondamentali.

116 Luglio / Agosto 2011 ~ Elettronica In


Corso di programmazione iPhone

fatto ciò, si avvierà Fig. 5 - Il nostro Hello World.


Listato 6 - Corpo del metodo Application. automaticamente
Interface Builder,
[self.window addSubview:viewController.view];
[self.window makeKeyAndVisible]; cioè il tool che
abbiamo visto
velocemente nelle
Tra parentesi tonde viene indicato il tipo di scorse puntate.
ritorno di questo metodo; in questo caso, un Il tool è strutturato
valore booleano. In ObjectiveC i valori possibili in modo differente
sono “YES” e “NO” invece dei classici “true” e da Xcode, infatti è
“false”. Successivamente abbiamo il nome del diviso in quattro
metodo; siccome esso accetta dei parametri, finestre chiave: una
deve essere inserito il carattere “:” per ognuno a sinistra chiamata
di questi. Il metodo in discussione accetta due “Library”, dove
parametri: un primo di tipo “UIApplication” possiamo trovare la
ed un secondo di tipo “NSDictionary”. maggior parte dei
L’etichetta “didFinishLaunchingWithOptions” componenti grafici,
è il nome del secondo parametro, infatti in una parte centrale,
ObjectiveC è obbligatorio scrivere il nome di chiamata come il
tutti i parametri dopo il primo (dalla prossima nome della vista
lezione inizieremo a scrivere il nostro primo che stiamo elabo-
metodo e tutto comincerà a diventare più rando (dove sono
chiaro). presenti tutti i componenti collegati alla nostra
L’implementazione di questo metodo è abba- vista) una terza con quattro tab fondamentali
stanza semplice, come possiamo vedere nel Li- dove andremo a lavorare per far comunicare
stato 6: consta di due righe di codice, che sono la vista con il controller e in cui si modificano
entrambe la chiamata di un metodo sull’ogget- gli elementi grafici, ed infine l’ultima parte,
to “window”, come denota la presenza delle che rappresenta lo schermo dell’iPhone su cui
parentesi quadre. andremo a posizionare gli elementi.
Nel listato in questione possiamo anche vedere Per prima cosa cerchiamo, nella finestra library,
come si accede ad una proprietà dell’oggetto, l’elemento label. Una volta trovatolo, facciamo
tramite la direttiva “self” (nel nostro pseudo- clic su di esso e, tenendo premuto il pulsan-
linguaggio era “this”). te del mouse, trasciniamolo nella finestra
Con “self.window” stiamo accedendo alla dell’iPhone.
proprietà “window” dell’istanza su cui stiamo Una volta posizionato l’elemento all’interno
lavorando; siccome questo è a sua volta un della finestra, rilasciamo il tasto del mouse.
oggetto, stiamo invocando su di esso il metodo Il risultato ottenuto dovrebbe essere simile a
“addSubview”, passandogli come parametro quello riportato nella Fig. 4.
una proprietà dell’oggetto “viewController”. Per cambiare il valore della nostra etichetta,
Vediamo adesso come è possibile realizzare
un’interazione con il pannello touch dell’ipho-
ne, inserendo oggetti grafici sui quali è pos- Listato 7 - Aggiungere la proprietà etichetta.
sibile agire tramite l’interfaccia che ci mette a
disposizione la Apple per la gestione dell’in- #import <UIKit/UIKit.h>

terfaccia grafica delle nostre applicazioni, ossia @interface HelloWorldViewController : UIViewController {


Interface Builder. UILabel *etichetta;
}
Per accedere ad Interface Builder dobbiamo
aprire, dal nostro project manager di Xcode, @property (nonatomic, retain) IBOutlet UILabel *etichetta;
la cartella Resources e fare doppio clic sul file @end
“HelloWorldViewController.xib”. Una volta

Elettronica In ~ Luglio / Agosto 2011 117


Corso di programmazione iPhone
Listato 8 - File HelloWorldViewController.m.

//
// HelloWorldViewController.m
// HelloWorld
//
// Created by Walter Dal Mut on 04/12/10.
// Copyright 2010 Walter Dal Mut. All rights reserved.
//

#import “HelloWorldViewController.h”

@implementation HelloWorldViewController

@synthesize etichetta;

/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
*/

/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/

/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}
*/

/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/

- (void)didReceiveMemoryWarning {
// Releases the view if it doesn’t have a superview.
[super didReceiveMemoryWarning];

// Release any cached data, images, etc that aren’t in use.


}

- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}

- (void)dealloc {
[super dealloc];
}

@end

118 Luglio / Agosto 2011 ~ Elettronica In


Corso di programmazione iPhone

Fig. 6 - Interface builder con integrazione del nostro codice.

facciamo semplicemente doppio-clic su di essa tramite il costrutto “@property”. Notate la pre-


e scriviamo la stringa che vogliamo rappresen- senza della parola chiave “IBOutlet”, a signifi-
tare (in questo caso “Hello World”). care che questa etichetta è collegata a Interface
Dopo aver eseguito questa operazione possia- Builder.
mo salvare tramite la scorciatoia da tastiera Prima di poter aprire il creatore delle viste
MELA+S e chiudere Interface Builder. dobbiamo ancora aggiungere la direttiva di
A questo punto siamo pronti per lanciare il sintesi all’interno del file “.m”; quindi apriamo
simulatore (possiamo avviarlo direttamente da quest’ultimo e la aggiungiamo.
X-Code con la combinazione di tasti MELA+R). Il codice completo è visibile all’interno del
Se abbiamo fatto tutto correttamente dovrem- Listato 8.
mo vedere il risultato di Fig. 5. Se ora andiamo a dare uno sguardo alla fine-
A questo punto modificheremo ulteriormente stra che contiene gli elementi grafici presenti
l’applicazione per creare un’interazione con il all’interno di Interface Builder e selezioniamo
programma scritto dal lato X-code, aggiungen- l’opzione “File’s Owner”, assicurandoci che
do un frammento di codice che farà cambiare il nella finestra a destra sia selezionata la tab
testo della label. “Connections”, noteremo che è apparsa magi-
Per farlo apriamo il file camente la chiave “etichetta”, come visibile in
“HelloWorldViewController.h” e creiamo una Fig. 6.
proprietà di tipo “UILabel”, come è possibile Questo è l’effetto della direttiva IBOutlet, che
vedere nel Listato 7. abbiamo inserito precedentemente all’interno
Con l’aggiunta di questo codice stiamo creando del nostro codice.
una proprietà “etichetta” di tipo “UILabel” e A questo punto dobbiamo ancora informare IB
poi iniziamo la generazione dei setter e getter che vogliamo collegare la nostra proprietà, de-

Elettronica In ~ Luglio / Agosto 2011 119


Corso di programmazione iPhone
Listato 9 - Modificare il metodo viewDidLoad per cambiare il valore della label.

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];

etichetta.text = @”Da Xcode...”;


}

finita in Xcode, con quella che te rimuovendo i caratteri “/*”


invece vediamo nell’ambiente prima del nome del metodo e
grafico. Per farlo dobbiamo poi “*/” alla fine della dichia-
fare clic sul cerchietto posi- razione del metodo. Questo
zionato a destra della nostra particolare metodo viene chia-
etichetta e mantenere premuto mato quando la nostra vista è
il pulsante del mouse mentre lo stata caricata. Ora cambiamo
trasciniamo; un collegamento il valore dell’etichetta impo-
di colore azzurro seguirà ogni stando una nuova stringa nella
movimento del mouse. proprietà “text” dell’oggetto
Portiamo il puntatore sulla la- “UILabel”; il metodo “viewDi-
bel posizionata all’interno della dLoad” dovrebbe apparire
vista del nostro iPhone: la label come nel Listato 9. Se avviamo
si borderà di azzurro e a questo il nostro progetto troveremo,
punto potremo rilasciare il al posto della stringa “Hello
pulsante del mouse; di fianco World”, quella che abbiamo
al nome “etichetta” apparirà scritto via codice, quindi “Da
un box con scritto “Label (Hel- Xcode...” come possiamo vede-
loWorld)”, indicante che ora re nella Fig. 7. Dalla prossima
possiamo controllare la label lezione del corso inizieremo ad
direttamente dal codice. interagire con il codice parten-
A questo punto apriamo il file do dall’interfaccia grafica e cre-
“HelloWorldViewController.m” eremo un altro progetto pratico
Fig. 7 - Modifica del valore e decommentiamo il metodo utilizzando un componente già
dell’etichetta dal codice. 
“viewDidLoad” semplicemen- disegnato dalla Apple.

rduino
la piattaforma open source alla portata di tutti
STARTER KIT CON ARDUINO UNO
kit composto da scheda Arduino UNO, cavo USB,
mini Breadboard a 170 contatti con 10 cavetti
cod: da 15 cm, piastra sperimentale (58,50 x 82,70mm),
ARDUINOUNOKIT 2 motori elettrici, fotoresistenza, termistore, LED,

55,oo
micropulsanti, transistor e molti altri componenti


necessari per cominciare ad utilizzare
questa potente piattaforma hardware.
IVA inclusa.

Via Adige, 11 • 21013 Gallarate (VA) Maggiori informazioni su questo prodotto e su tutte le altre apparecchiature sono disponibili sul sito
Tel. 0331/799775 • Fax. 0331/792287 www.futurashop.it tramite il quale è anche possibile effettuare acquisti on-line.

120 Luglio / Agosto 2011 ~ Elettronica In


di WALTER DAL MUT e FRANCESCO FICILI
Corso di programmazione iPhone

Corso di programmazione
PUNTATA 4
iPhone

I n questa quarta
puntata del nostro
corso vogliamo spen-
zando i problemi
legati a rotazione e
dimensionamento. In
dere qualche parola ultima analisi vedremo
sull’interfaccia utente un nuovo progetto pra-
dei dispositivi Apple: fa- tico, fatto utilizzando la
remo quindi una veloce Table View, forse il tipo
carrellata su tutti i con- di vista più usato nel
trolli grafici di cui essa mondo iPhone e legata
dispone e descriveremo alle App.
un primo esempio di in-
terazione utente-dispo- Interfaccia utente
sitivo. Successivamente L’iPhone, così come iPod Conosciamo l’interfaccia
parleremo di autorotating Touch, ha un display utente ed i controlli grafici,
ed autosizing, due inte- fulltouch; questo rappre- approfondendo il discorso
ressanti proprietà che senta l’unica interfaccia
permettono di adattare verso l’utente che su autorotating e autosizing,
la visualizzazione sullo possiamo utilizzare, dal concludendo con un
schermo quando si gira punto di vista program- progetto pratico realizzato
il dispositivo, analiz- matico, per generare
mediante la Table View.

Elettronica In ~ Settembre 2011 61


Corso di programmazione iPhone
Fig. 1 - Aggiungere il pulsante alla nostra interfaccia.

azioni che lavorino con il controller, nel modo Controller” ed il “View Controller” che abbia-
che abbiamo visto nel modello MVC. mo già visto ed utilizzato nella scorsa lezione.
Tutti i “design” grafici che possiamo fare su Altri Controllers li analizzeremo già da questa
iPhone, estendono la classe base di tipo UI- puntata, iniziando con il “TableViewControl-
View; questo concetto è fondamentale, infatti ler”; nelle prossime puntate utilizzeremo i
le etichette, i pulsanti, i picker e tutti gli altri restanti.
componenti visuali, sono estensioni di tale Il secondo gruppo, “Data Views”, riguarda
classe base. viste dedicate a risolvere problemi specifici,
I componenti grafici che ci vengono forniti come la “Table View” per le tabelle, la “Image
dalla Apple sono molteplici e possono essere View” per visualizzare immagini, la “Web
divisi in quattro categorie: View” (che utilizzeremo nelle prossime pun-
• Controllers;
• Data Views;
• Input & Values; Listato 1 - Aggiungere il prototipo nell’intestazione.
• Windows, Views & Bars.
#import <UIKit/UIKit.h>

I Controllers sono un metodo @interface HelloWorldViewController : UIViewController {


UILabel *etichetta;
per attaccare alla nostra }
vista dei controlli già rea-
- (IBAction) cliccaQui:(id)sender;
lizzati e pronti per l’uso; tra
questi spiccano i “Tab Bar @property (nonatomic, retain) IBOutlet UILabel *etichetta;
Controller”, i “Navigation
@end
Controller”, i “TableView

62 Settembre 2011 ~ Elettronica In


Corso di programmazione iPhone

tate per creare un nostro browser


web), la “Map View” per vedere le Listato 2 - Implementazione del metodo “cliccaQui”.
mappe di Google (e molte altre) e i
-(void)cliccaQui: (id)sender{
pickers per selezionare date oppure self.etichetta.text = @”L’utente ha fatto clic”;
valori a nostra scelta. }
Le “Input & Views” sono le più uti-
lizzate nel disegno personale delle
interfacce; tra esse troviamo le “Label”, i “But- generare le dovute informazioni all’interno
ton” per far interagire l’utente, le “Text Field” di Interface Builder. Come vedremo tra poco,
per raccogliere il testo che un utente inserisce, nell’implementazione della classe il tipo di
gli “Switch” e così via. ritorno sarà “void” e non IBAction, come ci
L’ultimo gruppo riguarda le “Windows, View aspetteremmo.
& Bars”, dedicate alla navigazione; qui trovia- Dopo questo abbiamo il nome del metodo,
mo la “Search Bar” per fare ricerche persona- “cliccaQui” e poi i parametri, come lasciano
lizzate, le “ToolBar” per la creazione di una intendere i due punti. Per i parametri dobbia-
propria barra personalizzata, per aggiungere mo sottolineare la presenza della parola chiave
contenuti e molto altro. “id”, in quanto il tipo non è definito, ma viene
Potete navigare in queste categorie diretta- stabilito a run-time; abbiamo già detto che
mente da Interface Builder e approfondirne la ObjectiveC è debolmente tipizzato e quindi
conoscenza tramite la documentazione in linea. possiamo, in certe circostanze, non avere un
In questo corso faremo uso dei controlli più tipo definito a priori. Notate che “id” è seguita
famosi ed utilizzati. dal nome della variabile, che in questo caso è
“sender”.
Lavoriamo sull’Hello World Sino ad ora abbiamo aggiunto la nostra “firma
Riprendiamo in mano il codice che abbiamo di metodo” o “prototipo”, se preferite; ora ne
scritto nella precedente lezione, cui vogliamo dobbiamo scrivere l’implementazione, quindi
aggiungere l’interazione con l’utente; per fare apriamo il relativo file “.m” ed aggiungiamo
questo dobbiamo in primo luogo aggiungere la nostra implementazione, come mostrato
un Button nella nostra vista, come abbiamo nel Listato 2. Qui abbiamo dichiarato il tipo di
fatto nella scorsa puntata tramite Interface ritorno come “void”; il placeholder “IBAction”
Builder (Fig. 1). Il componente grafico che introdotto nel file “.h” non esiste e serve solo
vogliamo aggiungere è il “Round Rect Button”, per l’utilizzo di Interface Builder.
per utilizzare il quale lo selezioniamo facendo Ora dobbiamo collegare il componente grafico
clic su di esso e lo trasciniamo all’interno della introdotto in Interface Builder con il codice;
vista. Una volta che l’abbiamo posizionato, allo scopo, apriamo la vista “HelloWorld-
vi facciamo doppio clic per inserire il testo al ViewController.xib”. Qui, se facciamo clic su
suo interno, mettiamo il testo “Clicca Qui” e “File’s Owner” e guardiamo il box “Connec-
premiamo Invio per confermare. Per inviare le tions”, notiamo che si è creato un box “Recei-
azione al controller dobbiamo creare il nostro ved Actions” con il nome del metodo da noi
primo metodo, che poi collegheremo alla vista sviluppato (Fig. 2).
tramite Interface Builder; allo scopo, all’interno Come abbiamo fatto per collegare la label
del file HelloWorldViewController.h aggiun- al codice, nello stesso modo facciamo clic e
giamo una action (metodo), come possiamo trasciniamo la “cordina” azzurra sul pulsante;
vedere nel Listato 1. sempre nella Fig. 2, vediamo che invece di
Abbiamo già visto che il simbolo “-” dichiara eseguire subito il collegamento, come era suc-
un metodo di istanza e non di classe. Tra le cesso precedentemente, appare un box grigio
parentesi tonde troviamo il corrispettivo di con diverse possibilità. Esistono molti tipi di in-
“IBOutlet” per quello che riguarda le azioni, terazioni disponibili, ma quella che ci interessa
ossia “IBAction”. Anche questo non ha al- per ora è il “Touch Up Inside”; in breve, ciò
cun senso programmatico, ma serve solo per significa che andremo a fare il touch su di esso.

Elettronica In ~ Settembre 2011 63


Corso di programmazione iPhone
Fig. 2 - Selezione del tipo di azione.

Una volta selezionata questa informazione, si è tasto del mouse, trasciniamolo fino al bordo
formato il link nel box “Connections”. destro (Fig. 3). A questo punto lo spazio a
A questo punto possiamo avviare la nostra disposizione per la nostra etichetta è grande a
App e fare clic sul pulsante: vedremo che la sufficienza. Di tutti i controlli grafici è possibile
nostra stringa non è completa, dato che nel po- modificare le dimensioni, perciò possiamo fare
sizionare l’etichetta nella lo stesso lavoro anche con il pulsante e tutte
vista, abbiamo lasciato la le altre viste che utilizzeremo. Se proviamo a
dimensione predefinita, riavviare la nostra applicazione e facciamo clic,
ma adesso, con un testo notiamo che ora la stringa non è più troncata,
lungo quale “L’utente ha ma viene visualizzata per intero. Ricordate che
fatto clic”, il campo viene dobbiamo sempre liberare la memoria, quindi
tagliato e in esso vengono inserite la chiamata al metodo “release” nel
inseriti dei puntini per metodo “dealloc”, come mostrato nel Listato 3.
indicare che il contenuto
continua. Per aumentare Autorotating e Autosizing
la dimensione del campo Autorotating ed autosizing sono due proprietà
possiamo riaprire IB e fare fornite dalla Apple: la prima riguarda la capa-
clic sulla label: viene quin-
di mostrato un contorno Listato 3 - Liberare la memoria dalla nostra etichetta.
con diversi piccoli qua-
drati, dove selezioniamo - (void)dealloc {
[etichetta release];
Fig. 3 - Dimensionamento quello di destra; facendo [super dealloc];
dell’etichetta. clic e tenendo premuto il }

64 Settembre 2011 ~ Elettronica In


Corso di programmazione iPhone

Listato 4 - Metodo per il controllo dell’orientazione del dispositivo.


// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

Listato 5 - Abilitare l’autorotating.


// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return YES;
}

cità del dispositivo di capire se è stato ruotato dello schermo si scambiano e quindi le viste
dall’utente e quindi riadattare la vista che si progettate per una visualizzazione “Portrait”
sta visualizzando per adeguarsi al cambio di non saranno adatte a quella “Landscape”.
dimensione dello schermo; questo perché, se La gestione dell’autosizing è invece possibile
pensiamo all’iPhone 3GS, si passa da 320x480 tramite il menu “View Size”, direttamente da
pixel in posizione verticale (formato portrait) a Interface Builder (Fig. 5) tramite il box a destra,
480x320 quando si è in modo landscape, ovvero chiamato proprio “Autosizing”.
orizzontale. L’autosizing è molto comodo, in quanto per-
Intercettando autorotating possiamo sce- mette lo stretching automatico dei componenti;
gliere se adattare semplicemente la vista però fate attenzione che non tutte le risorse
eseguendo l’autosizing, oppure spostare i possono essere scalate con semplicità. Lascia-
componenti programmaticamente o, anco- mo alla vostra curiosità l’approfondimento di
ra, cambiare vista. Per attivare l’autorota- questo componente; per i nostri scopi ci dedi-
ting del dispositivo, dobbiamo aprire il file cheremo principalmente alla gestione di una
“HelloWorldViewController.m” e trovare il singola orientazione.
metodo “shouldAutorotateToInterfaceOrienta-
tion”. Nel Listato 4, questo metodo ritorna un MultiViews & Controllers
boolean e nella configurazione decommentata Come abbiamo già detto, tutti i componenti
viene ritornata la vista “Portrait”; se vogliamo che possono essere posizionati sullo schermo
gestire tutte le orientazioni disponibili pos- sono delle View ed estendono la classe base
siamo semplicemente eseguire il “return” di “UIView”; per questo motivo una “UILabel” è
“YES”, come si vede nel Listato 5.
Se ora avviamo la nostra applicazione, trami-
te il menu del simulatore “Hardware” e poi
“Ruota a sinistra”, vediamo che automatica-
mente la nostra vista si è riconfigurata per la
nuova orientazione (Fig. 4).
Se volessimo gestire solo le viste orizzontali,
dovremmo utilizzare il metodo “shouldAutoro-
tateToInterfaceOrientation” e utilizzare la costan-
te “UIInterfaceOrientationLandscapeLeft” al posto
di “Portrait” (Listato 6).
Quando orientiamo il dispositivo dobbiamo
fare attenzione alle viste, perché le dimensioni Fig. 4 - Rotazione della vista.

Elettronica In ~ Settembre 2011 65


Corso di programmazione iPhone
Listato 6 - Orientare il dispositivo in orizzontale.
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft); //orizzontale-sinistra
}

concettualmente identica alla vista che abbia- ora una seconda, ed abbiamo anche il codice di
mo progettato nel terza puntata. Siccome tutte un altro controller.
estendono la classe base UIView, possiamo Per aggiungere la vista del controller appena
gestirle allo stesso modo ed avranno tutte un creato alla vista del componente base, non
preset di metodi e proprietà di base. dovremo fare altro che creare il controller con
Con MultiViews si vuole indicare che è possi- la vista associata in via programmatica ed
bile mettere in una vista tante altre viste, come aggiungere la sua vista a quella del primo. Il
abbiamo già fatto con la label dentro la nostra Listato 7 riguarda proprio questa casistica.
view. Nella prima riga stiamo creando un nuovo
controller di tipo “SecondViewController”
Creare nuovi Controllers e legare le Viste collegando la vista tramite il suo file “XIB”;
Come per le viste, è possibile generare e gestire eseguiamo il metodo “alloc” e poi “initWi-
più controller sia singolarmente che innestati thNibName” come costruttore del oggetto
uno dentro l’altro. Per farlo, non dobbiamo fare (Controller, in questo caso).
altro che creare un nuovo controller con asso- Alla seconda riga, invece, stiamo chiamando il
ciata una vista: facendo MELA+N sul progetto, metodo “addSubView” sulla proprietà “view”
aggiungiamo un file di tipo “UIViewController del controller su cui stiamo lavorando: in prati-
subclass” (Fig. 6). Attenzione a spuntare la ca stiamo aggiungendo una sotto-vista a quella
selezione “With XIB for user interface”). corrente. Come potete immaginare, le dimen-
Facendo clic su next in basso a destra, aggiun- sioni sono importanti e dovete lavorare molto
giamo il nome alla classe “SecondViewControl- con IB per costruire la seconda interfaccia ed
ler” e proseguiamo. attaccarla bene alla vista.
Nel nostro progetto, oltre alla vista “Hel- Prima di passare alle TableView dobbiamo
loWorldViewController.xib” ne è disponibile sottolineare che allocando il controller in quel

Fig. 5 - Gestione dell’autosizing. Fig. 6 - Creare un nuovo controller.

66 Settembre 2011 ~ Elettronica In


Corso di programmazione iPhone

Come indica il nome, è il Fig. 8 - La nostra App


Listato 7 - Aggiungere una vista ad un altra. controller radice, ovvero sul modello Table View.
il primo. Vediamo che
SecondViewController *controller = [[Second-
ViewController alloc] initWithNibName:@”Sec questo particolare oggetto
ondViewController” bundle:nil]; estende la classe base
[self.view addSubView:controller.
view];
“UITableViewControl-
ler”, la quale è un’esten-
sione di quella utilizzata
modo, non possiamo poi liberarlo nel metodo nei precedenti progetti di
“dealloc”, in quando non è nello “scope” del tipo “UIViewController”.
nostro oggetto, quindi le possibilità sono due: Ciò perché, tramite que-
lo rilasciamo subito oppure dobbiamo intro- sta classe base, vengono
durlo come proprietà di istanza per poi averlo introdotte le funzionalità
visibile e poterlo rilasciare in modo consono. che estendono un norma-
Abbiamo fatto questa breve analisi del Mul- le controller.
tiviews perchè lo utilizzeremo subito per le Prima di introdurre dei
TableView e per i progetti che andremo a dati all’interno della vista,
realizzare nello sviluppo del corso. dobbiamo analizzare due
metodi che vediamo nel
Progetto Pratico con Table View Listato 8.
Le Table View sono veramente utili ed ab- Il primo metodo, “num-
bastanza semplici da utilizzare; sono forse il berOfSectionsInTable-
componente grafico maggiormente utilizzato View”, deve ritornare un numero intero che ci
e personalizzato. La Fig. 7 mostra la struttura dice in quante sezioni è divisa la nostra tabella;
tipica di una tabella per iPhone. questo perché possiamo dividere la tabella in
Tralasciamo la parte di colore azzurro in alto, sezioni e per ognuna avere dei dati specifici. In
che rappresenta la navigation bar; le Table questo esempio ci sarà sempre una sola sezio-
View in iOS sono semplicemente delle righe, ne, ma sappiate che potete dividere la tabella in
ognuna delle quali corrisponde ad una UI- più parti.
View. Sta a noi utiliz- Il secondo metodo, “numberOfRowsInSec-
zare quella predefinita tion”, si occupa di dire quante righe sono
oppure crearne alcune a presenti in una sezione specifica. Il parametro
piacimento. section, di tipo intero, indica che il core di iOS
Per creare il nostro pro- sta elaborando la sezione specificata e che dob-
getto chiudiamo il prece- biamo ritornare il numero di righe che voglia-
dente e ne iniziamo uno mo stampare per questa sezione.
nuovo; indichiamo che Per introdurre dei dati ci baseremo su un
vogliamo crearne uno di modello che, per semplificare, sarà il tipo
tipo “Navigation Based “NSString”; se vogliamo dei tipi più complessi
Application” e chiamia- possiamo creare un’estensione di “NSObject”
molo “TableViewExam- ed utilizzarla come per il tipo base stringa.
ple”. Una volta creato Per prima cosa dobbiamo creare l’array che an-
il progetto, avviamo il drà a contenere i nostri modelli di dato, quindi
simulatore per vedere il nel nostro file “.h” andiamo a fare la dichiara-
risultato nella Fig. 8. zione di un “NSMutableArray” e sintetizziamo
Iniziamo subito a quest’ultimo nell’implementazione della classe.
“colorare” il codice per Il Listato 9 contiene entrambi i file da modifica-
renderlo utile; il file che re allo scopo.
ci interessa si chiama Ricordate di andare subito a liberare la me-
Fig. 7 - Esempio di Table View. “RootViewController”. moria; non abbiamo bisogno di liberare ogni

Elettronica In ~ Settembre 2011 67


Corso di programmazione iPhone
Listato 8 - Metodi base delle Table View.
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}

// Customize the number of rows in the table view.


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 0;
}

singolo oggetto nell’array, in


Listato 9 - Dichiarare l’array nell’implementazione e nell’intestazione. quanto sarà “NSMutableArray”
a farlo per noi.
//RootViewController.h
#import <UIKit/UIKit.h> Ora che abbiamo dichiarato
i dati possiamo allocare la
@interface RootViewController : UITableViewController {
NSMutableArray *dati;
memoria necessaria all’array
} e introdurvi alcune strighe,
per poi visualizzarle dall’app.
@property (nonatomic, retain) NSMutableArray *dati;
Nel metodo “viewDidLoad”
@end aggiungiamo il codice necessa-
------ rio, come possiamo vedere nel
Listato 10.
//RootViewController.m
@implementation RootViewController
A questo punto abbiamo
aggiunto i dati; non ci resta
@synthesize dati; che informare il controller che
//Resto dell’implementazione vogliamo visualizzarli nella
tabella. Nel metodo “numbe-
- (void)dealloc {
[dati release]; rOfRowsInSection” chiediamo
al componente “NSMutable-
[super dealloc];
}
Array” il numero di elementi
e restituiamo questo conteggio

Listato 10 - Aggiungere elementi all’array.


- (void)viewDidLoad {
[super viewDidLoad];

// Uncomment the following line to display an Edit button in the navigation bar for this view
controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;

//Allochiamo l’array
dati = [[NSMutableArray alloc] init];
//Creazione della stringa
NSString *stringa = @”Prima stringa”;
//Aggiungiamo la stringa all’array
[dati addObject: stringa];

//Creazione della stringa


NSString *stringa2 = @”Seconda stringa”;
//Aggiungiamo la stringa all’array
[dati addObject: stringa2];
}

68 Settembre 2011 ~ Elettronica In


Corso di programmazione iPhone

nel metodo “numberOfRowsInSec-


tion”, come vediamo nel Listato Listato 11 - Informare il controller dei dati disponibili.
11.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSecti
Ora ci manca solo un altro passo: on:(NSInteger)section {
informare la vista che vi sono dei return [dati count];
}
dati da visualizzare nelle celle. Per
fare questo esiste un altro metodo
fondamentale, che si chiama “cel-
Listato 12 - Il metodo di visualizzazione delle celle.
lForRowAtIndexPath”. Prima di
scrivere il codice dobbiamo sapere - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAt
che le TableView sono divise in IndexPath:(NSIndexPath *)indexPath {
celle, ossia “Cells”, che contengono
static NSString *CellIdentifier = @”Cell”;
i dati da visualizzare; per ragio-
ni di riutilizzo e gestione della UITableViewCell *cell = [tableView dequeueReusableCellWithIdent
ifier:CellIdentifier];
memoria, non sono sempre tutte if (cell == nil) {
disponibili. Il controller “UITable- cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCe
llStyleDefault reuseIdentifier:CellIdentifier] autorelease];
ViewController” le inserisce in una }
coda, evitando di caricarle tutte in
memoria, riutilizzandole e renden- // Configure the cell.

do disponibili solo quelle che sono return cell;


realmente visualizzate dall’utente; }
perciò è possibile avere un elenco
molto lungo senza incorrere in pro-
blemi di memoria. Listato 13 - Configurare la cella per la visualizzazione.
Analizziamo ora il metodo che
// Configure the cell.
serve a rendere disponibili i dati NSString *stringa = [dati objectAtIndex:indexPath.row];
(Listato 12). Come possiamo cell.textLabel.text = stringa;
vedere, questo metodo ha due return cell;

parametri: il primo è la vista asso-


ciata al controller UITableView ed Listato 14 - Cast esplicito di una istanza di tipo NSString.
il secondo è un oggetto chiamato
“NSIndexPath”. Questa struttu- NSString *stringa = (NSString *)[dati objectAtIndex:indexPath.row];
ra ingloba tutte le informazioni cell.textLabel.text = stringa;
return cell;
che riguardano la cella che si sta
configurando, quindi la sezione di
cui fa parte, la riga che si deve configurare, più ga; fatto ciò, configuriamo la cella assegnando
altre informazioni. questo riferimento alla proprietà text della cella
Nelle prime righe si configura la parte base del- stessa. A questo punto avviamo la nostra App
la cella e la sua estrazione dalla coda. Se questa e le celle ora visualizzeranno il testo da noi
esiste, viene direttamente utilizzata, altrimenti richiesto, come si vede nella Fig. 7.
viene creata. Noi andremo a lavorare più in Prima di terminare, sottolineiamo che quan-
basso, dove è stato posizionato il commento do estraiamo l’oggetto dall’array dobbiamo
“Configure the cell”. Come mostra il Listato eseguire il “cast” del tipo, che in questo caso
13, dobbiamo inserire solo tre righe, al fine di è “NSString”. Tale esecuzione è descritta nel
rendere visibile il dato nella cella indicata dalla Listato 14.
proprietà “row” dell’oggetto “IndexPath”. Nella prossima puntata riutilizzeremo questa
Per costruire la cella stiamo ricevendo l’oggetto applicazione integrando la “Navigation Bar”, la
stringa dal container di tipo “NSMutableAr- quale ci permette di navigare nei contenuti del-
ray” tramite il metodo “objectAtIndex” e lo la nostra applicazione ogni qual volta facciamo

assegnamo alla variabile locale chiamata strin- clic su una singola cella di essa.

Elettronica In ~ Settembre 2011 69


di WALTER DAL MUT e FRANCESCO FICILI
Corso di programmazione iPhone

Corso di programmazione
PUNTATA 5
iPhone

I n queste pagine parti-


remo usando il proget-
to di tipo “Navigation
singolo contenuto
selezionato dalla
tab. Per prima cosa
Based Application” occupiamoci di spiegare
descritto nella scorsa cos’è e come si usa la
puntata, per spiegarvi Navigation Bar, la quale
come gestire la navi- è uno strumento utilis-
gazione all’interno dei simo nelle applicazioni
contenuti. Poi faremo sviluppate per iPhone e
una veloce incursione iPad; allo scopo, dobbia-
nel mondo dei pickers mo “riesumare” i concet-
per la selezione di date, ti esposti nella quarta
orari o nostri contenuti puntata e in particolare
e concluderemo con un il progetto “Navigation Scopriamo come possiamo utilizzare la Navigation
nuovo progetto prati- Based Application”, Bar per gestire la navigazione dei contenuti e
co dove andremo ad perché questo ingloba
impariamo ad usare i pickers, utili per selezionare
utilizzare una TabBar la Table View. In tale
e le collegheremo un Na- progetto non abbiamo date, orari o contenuti. Vediamo anche un
vigation Controller per creato direttamente la progetto pratico basato sull’uso di TabBar e
la navigazione di ogni Table View in quanto, Navigation Controller.

Elettronica In ~ Ottobre 2011 77


Corso di programmazione iPhone
Fig. 1 - Il titolo nella Navigation Bar. per la navigazione dei Fig. 2 - Aggiungere un controller al nostro progetto.
contenuti, si è dimo-
strata veramente utile
e sufficiente la Naviga-
tion Bar.

Navigation Bar
Questo componente
serve, ad esempio,
per introdurre delle
viste nei contenuti da
navigare; se non lo
utilizziamo, quando
vogliamo aggiungere
una vista dobbiamo far-
lo sfruttando il metodo
“addSubView” (come
è stato, pur sommaria-
mente, spiegato nelle della selezione di una riga della tabella. Per
precedenti puntate) e creare questo componente facciamo MELA+N
dovremmo anche fare sulla cartella “Classes” del nostro progetto e se-
in modo da rimuo- lezioniamo “Add” e poi “New File...”. Quando
vere le viste stesse si apre la finestra di selezione, indichiamo che
per ritornare nelle precedenti, utilizzando il vogliamo creare un nuovo UIViewController
metodo “removeFromSuperView”. Lavorando (Fig. 2) facendo attenzione a selezionare la voce
con la Navigation Bar (NavBar) l’aggiunta e la riguardante la creazione della vista associata.
rimozione vengono gestite al suo interno, il che Chiamiamo il nostro controller “Detail-
ci garantisce una programmazione semplice e ViewController”. Una volta generato il co-
veloce. dice, Xcode mette i tre file del nostro nuovo
Riapriamo ora il nostro vecchio progetto “Ta- controller all’interno della nostra folder “Clas-
bleViewExample” e iniziamo ad aggiungere ses”; per ottenere un progetto “pulito”, spostia-
le informazioni per riempire la nostra barra mo la vista, quindi il file “.xib”, nella cartella
di navigazione; per prima cosa, nel metodo “Resources” (Fig. 3).
“viewDidLoad” andiamo ad aggiungere un All’interno di questo nuovo controller dobbia-
titolo al nostro controller. Questa tecnica viene mo creare due elementi, il primo di tipo “NS-
molto utilizzata per dare un nome ai ViewCon- String” (è il nostro modello di dati) ed un altro
troller; per applicarla, agiremo sulla proprietà di tipo “UILabel”, che serve a collegarlo, trami-
“title”, come mostrato nel Listato 1. te l’Interface Builder, al codice e poi far agire il
Se ora avviamo la nostra applicazione, ve- nostro controller dai dati alla visualizzazione.
diamo che il titolo viene
automaticamente inserito Listato 1 - Assegnare il titolo al controller.
all’interno della barra di
navigazione (Fig. 1). - (void)viewDidLoad {
A questo punto siamo pronti [super viewDidLoad];
per andare a “spingere” i no- // Uncomment the following line to display an Edit button in the
stri controller personalizzati navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
all’interno della Navigation
Bar; allo scopo dobbiamo self.title = @”Elettronica IN”;
creare un nuovo controller //Resto dell’implementazione...

che rappresenterà il dettaglio

78 Ottobre 2011 ~ Elettronica In


Corso di programmazione iPhone

Fig. 3 - Situazione Il procedimento è identico


del nostro progetto. a quello dell’HelloWorld Listato 2 - L’intestazione del controller di visualizzazione.
che abbiamo già visto
//DetailViewController.h
nelle precedenti puntate. #import <UIKit/UIKit.h>
Nella vista aggiungiamo @interface DetailViewController : UIViewController {
UILabel *etichetta;
la label ed aggancia- NSString *dato;
mola al codice tramite }
la direttiva IBOutlet; a
@property (nonatomic, retain) IBOutlet UILabel *etichetta;
questo punto eseguiamo @property (nonatomic, retain) NSString *dato;
il collegamento visuale.
@end
In aggiunta utilizziamo
un oggetto di tipo “NS-
String”; ora il nostro file cercare l’implementazione del metodo “didSe-
“.h” dovrebbe risultare lectRowAtIndexPath”; ciò perché, come dice
come il Listato 2. il nome del metodo, si tratta di un’azione che
Ricordiamo che il compito viene eseguita quando un utente seleziona una
di questo controller è ac- riga della nostra tabella.
cedere alla vista passando All’interno di questo metodo c’è una parte
i dati da visualizzare; in di codice che andremo a riutilizzare com-
questo caso abbiamo il pletamente, in quanto riguarda proprio il
modello dei dati (oggetto funzionamento incrociato di navigazione e
NSString) e l’etichetta che visualizzazione. Nel Listato 4 vediamo il codi-
li rappresenta (UILabel). ce necessario per il funzionamento completo
Per collegare il modello serve solo un sempli- della NavBar, dove notiamo che è stato sempli-
ce collegamento nel metodo “viewDidLoad”, cemente rimosso il commento multilinea.
come mostra il Listato 3. Alla riga 2 stiamo allocando il controller del
Adesso il controller è pronto; non ci resta che dettaglio sulla selezione dell’utente, informan-
ritornare a lavorare sulla TableView, in modo do il compilatore che la sua vista deve essere
da unire il tutto sotto un’unica bandiera; in elaborata tramite il “nib” file chiamato “Detail-
pratica allocheremo il controller creato e dire- ViewController.xib”.
mo alla Navigation Bar di renderlo disponibile Alla riga 3, invece, stiamo lavorando con la
agli utenti. Sarà nostra premura andare ad in-
formare il controller del dettaglio di tutte le in-
formazioni che devono essere visualizzate; allo Listato 3 - Assegnare alla vista i dati del modello.
scopo passeremo il modello di dati al controller
//DetailViewController.h
di dettaglio e questo si occuperà di passare alla - (void)viewDidLoad {
sua vista i dati da visualizzare (Listato 3). [super viewDidLoad];
self.etichetta.text = dato;
Dunque dobbiamo aprire il nostro “Root- }
ViewController”, ovvero la TableView e qui

Listato 4 - Utilizzare la navigazione.


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@”DetailVie
wController” bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];

Elettronica In ~ Ottobre 2011 79


Corso di programmazione iPhone
Listato 5 - Modificare il metodo per passare i dati al controller di dettaglio.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *stringa = (NSString *)[self.dati objectAtIndex:indexPath.row];

DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@”DetailView


Controller” bundle:nil];
detailViewController.dato = stringa;
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];

Fig. 4 - Vista del dettaglio inseritabarra di navigazione. della riga andando ad agire sulla proprietà
dal Navigation Controller. In ogni controller è “etichetta”, facendo comparire il valore della
presente la proprietà riga selezionata; per fare questo dobbiamo
“navigationController” prendere dall’array utilizzato per la table view
che riguarda proprio il modello e assegnare la stringa all’etichetta
la Navigation Bar; per del “DetailViewController” (Listato 5).
“spingere” (push) un A questo punto siamo pronti per avviare
nuovo controller, dob- il nostro progetto: quando il simulatore ha
biamo agire su di essa. caricato il sistema, facciamo clic su una delle
Successivamente ve- due righe che abbiamo settato e vedremo che il
diamo la direttiva che Navigation Controller si occuperà, tramite una
rilascia il controller che transizione, di rendere disponibile la vista di
abbiamo inserito nello dettaglio.
stack di visualizzazione; Questa utilizzerà il modello dei dati per
ciò perché la Navigation visualizzare il testo selezionato (Fig. 4).
Bar esegue una “retain” Se analizziamo questa vista, notiamo che il
su tale controller, ovve- Navigation Controller ha aggiunto un pulsante
ro esegue la “release” (sulla sua barra) che ci permette di ritornare
quando, invece, rimuo- alla vista precedente senza dover assoluta-
veremo il controller mente aggiungere una sola riga di codice. Per
dalla pila. rendere il tutto perfetto dobbiamo aprire il file
La “release” garantisce del dettaglio ed aggiungere il titolo tramite la
il riciclo di memoria del proprietà “title” del controller in questione,
componente allocato. come fatto nel Listato 6.
Se ora avviamo il nostro progetto e facciamo A questo punto abbiamo terminato la stesura
clic su una riga, vediamo che viene inserita la del nostro progetto iniziato nella scorsa pun-
nostra vista di dettaglio con un’animazione. tata; ricordate che dovete sempre rilasciare la
Modifichiamo ancora il metodo di selezione memoria anche nel dettaglio, perché il Naviga-

Listato 6 - Aggiungere il titolo al controller di dettaglio. Listato 7 - Liberare la memoria nel controller di dettaglio.
- (void)viewDidLoad { - (void)dealloc {
[super viewDidLoad]; dato = nil;
[etichetta release];
self.title = @”Dettaglio”; [super dealloc];
}
self.etichetta.text = dato;
}

80 Ottobre 2011 ~ Elettronica In


Corso di programmazione iPhone

tion Controller utilizzerà la “release” quando


facciamo clic sul pulsante per ritornare al
controller precedente. Il Listato 7 mostra come
liberare tutte le risorse allocate.

Progetto pratico con il TabBar controller


Il tab bar controller è un altro componente
fondamentale delle applicazioni iOS: il suo
principale obiettivo è permettere la naviga-
zione indiretta tra i contenuti. Esso si dispone
graficamente nella parte bassa della nostra
applicazione e permette all’utente di selezio-
nare quale vista visualizzare, passando da una
all’altra senza perdere la navigazione eseguita.
In Fig. 5 possiamo vedere un tipico esempio di Fig. 6 - Generare un UITableViewController.
App strutturata con TabBar, che eseguiremo
tra poco. un controller di tipo TableViewController ed
Come potete vedere, la barra di navigazione un secondo di tipo UIViewController.
indiretta è posizionata in basso e permette la Questa configurazione, che andremo a rea-
navigazione tra due diversi controller/viste. lizzare, è infatti il tipico standard delle App
Per realizzare questo nuovo progetto avviamo gestionali che trovate nell’App store.
il nostro Xcode e iniziamone uno di tipo “Tab Per realizzare questo set dobbiamo smontare
Bar Application”; quando ci viene richiesto, la parte visuale dell’applicazione che abbiamo
impostiamo come nome “TabBarExample”. creato (tramite il generatore di Xcode) e ricom-
Una volta creato il progetto, possiamo compi- porla con tutti i componenti di cui abbiamo
lare ed eseguire il codice per avere un risultato bisogno.
simile a quello mostrato nella Fig. 5. Ora dobbiamo creare un nuovo controller di
Adesso analizziamo tipo UITableViewController; allo scopo faccia-
il codice che è stato mo MELA+N sulla folder “Classes” e generia-
generato: apriamo mo una classe di tipo UIViewController (Fig.
il nostro delegato 6); successivamente indichiamo che quest’ul-
dell’applicazione, tima deve essere una sottoclasse di UITable-
quindi il file “Tab- ViewController e che vogliamo collegare una
BarExampleAppDe- vista in XIB.
legate”; vediamo
che qui è stato uti-
lizzato il controller
di tipo “UITabBar-
I pickers
Controller”.
La configurazione I pickers sono dei particolari componenti grafici che
di questo compo- permettono la selezione, da parte dell’utente, di un
set pre-organizzato di valori. Esistono due tipologie di
nente non è im- tali componenti:il “Picker View” ed il “Date Picker”; il
mediata ed esula primo si occupa di far selezionare dei dati completa-
dagli scopi di questa mente gestiti dal programma, mentre il secondo serve
puntata del corso; prevalentemente per le date. Per l’utilizzo del primo
è più interessante componente si devo implementare due interfacce: la
costruire il nostro prima per la gestione dei dati ed una seconda, invece,
per il delegato dell’applicazione e quindi per l’interazio-
nuovo progetto per ne utente-dispositivo. Il secondo tipo, invece, richiede
integrarvi la Navi- l’implementazione di una sola interfaccia.
Fig. 5 - Esempio di TabBar application. gationBar mediante

Elettronica In ~ Ottobre 2011 81


Corso di programmazione iPhone
A questo punto, se nostro obbiettivo
aprite la vista asso- sarà scomporre
ciata a tale controller questo progetto
potete vedere che il per arrivare alla
risultato è proprio situazione visibile
quello che volevamo. in Fig. 7.
Ora tocca al tipo UI- Nel nostro “in-
ViewController, che spector” dedicato
dobbiamo generare ai componenti
come fatto per il Ta- visuali, è stato inse-
bleView Controller, rito dal generatore
ovvero rimuovendo di codice anche
Fig. 7 - Il progetto del TabBar
la spunta di tipo Ta- il controller di
in InterfaceBuilder.
ble, (vedere in Fig. 6); tipo TabBar; tutti
siccome quando ab- i controller che
biamo generato il nostro progetto, Xcode ci ha andremo ad ag-
già regalato la vista classica (il relativo file ha il giungere verranno
nome standard “FirstViewController”) possia- inseriti qui.
mo evitare di crearne una seconda e riutilizzare Per prima cosa
l’oggetto già generato da Xcode. Se volete rimuoviamo
potete comunque generare tutti i controller di entrambe le viste;
cui avete bisogno ed inserirli nella TabBar. allo scopo, selezio- Fig. 8 - Aggiunta del controller.
Facciamo clic su MainWindow.xib per aprire niamole dal box
XIB e vedere la struttura di questa vista princi- e premiamo il tasto Canc della tastiera. Una
pale: nella TabBar sono presenti le due View. Il volta rimosse, iniziamo ad aggiungere il primo

Fig. 9 - Assegnazione della Navigation Bar ad un Controller.

82 Ottobre 2011 ~ Elettronica In


Corso di programmazione iPhone

Listato 8 - Configurazione della nostra cella.


//Resto dell’implementazione della classe TableViewController
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *CellIdentifier = @”Cell”;

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];


if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]
autorelease];
}

// Configure the cell...


cell.textLabel.text = @”Elettronica IN”;

return cell;
}
//Resto dell’implementazione della classe TableViewController

Listato 9 - Utilizzare la Navigation Bar per visualizzare il secondo controller nella navigazione.
#pragma mark -
#pragma mark Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {


// Navigation logic may go here. Create and push another view controller.

FirstViewController *detailViewController = [[FirstViewController alloc] initWithNibName:@”FirstView”


bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];

controller: cerchiamo negli oggetti disponibili “viewDidLoad”) e modifichiamo la proprietà


il tipo “Navigation Controller” e trasciniamolo “title” assegnandole il titolo “Tabella”; a questo
nel box (Fig. 8); a questo punto possiamo “apri- punto possiamo avviare la nostra applicazione,
re” il componente facendo clic sulla freccina a allorché vedremo che è composta dalla barra in
sinistra e selezionando ViewController. Attra- basso, ossia la TabBar, e dalla barra di navi-
verso la sezione Identity Inspector (tipicamente gazione (in alto). Il contenuto è la tabella che
a destra in Xcode) andiamo ad assegnare all’at- abbiamo appena generato (Fig. 10).
tributo class il nome “TableViewController” Prima di andare ad agganciare il secondo
che abbiamo precedentemente creato. controller alla nostra vista, mettiamo al lavoro
A questo punto la situazione dovrebbe la nostra Navigation Bar, andando ad inserire
essere come appare in Fig. 9. Ricordate il codice necessario per navigare nei contenuti.
di andare nell’implementazione del file Invece di creare un nuovo controller, riuti-
“TableViewController.m” a sistemare il lizziamo il componente FirstViewController;
numero di sezioni e di celle da visualizzare; allo scopo andremo a lavorare nel metodo di
per fare presto, mettete una sola sezione ed selezione della riga e inseriremo il controller.
una sola cella e, nella visualizzazione delle Aggiungiamo la direttiva di importazione
celle, assegnate a queste ultime una stringa del “FirstViewController.h” in testa al nostro
fissa, come fatto nel Listato 8. Prima di av- TableViewController ed inseriamo il codice
viare l’applicazione, aggiungiamo il titolo al di utilizzo della Navigation Bar, come fatto
controller (andando a decommentare il metodo nel Listato 9. Avviando ora l’applicazione e

Elettronica In ~ Ottobre 2011 83


Corso di programmazione iPhone
Listato 10 - Utilizzo della navigazione da un UIViewController.
- (void)premutoPulsante:(id)sender
{
FirstViewController *detailViewController = [[FirstViewController alloc] initWithNibName:@”FirstView”
bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}

selezionando la riga nella tabella, il Navigation momento dobbiamo


Controller “spingerà” il “FirstViewController” aprire la vista asso-
e lo renderà visibile. ciata al controller
A questo punto siamo pronti per aggiungere “FirstView.xib” e
il secondo controller alla TabBar; agganciamo collegare la IBAc-
anche a questo componente la sua persona- tion con il pulsante
le Navigation Bar, perché la Tab Bar separa all’evento “TouchUp
completamente i contenuti e quindi ognuno di Inside”. Il codice per
questi ha una sua personale linea della vita. utilizzare la naviga-
Per aggiungere il secondo controller dobbia- zione è lo stesso che
mo accedere ad Interface Builder tramite il file abbiamo utilizza-
MaiWindow.xib ed eseguire la stessa proce- to nel metodo di
dura, ma utilizzando il FirstViewController selezione di una
invece del TableViewController. Ora possiamo riga all’interno del
avviare l’applicazione, da cui risulteranno TableViewControl-
due componenti nella TabBar e due barre di ler; il risultato per
navigazione distinte per utilizzare la barra
i due controller creati di navigazione sulla
(Fig. 11). pressione del pul-
Ora non ci resta che sante è espresso nel
utilizzare anche il Na- Listato 10.
vigation Controller nel Se avviamo ora Fig. 11 - Due TabBar per la gestione
FirstViewController. l’applicazione, di contenuti distinti.
Per fare questo aggiun- possiamo utilizzare
giamo un pulsante alla le due tab e navigare nei contenuti, passando
vista e con una Action dall’una all’altra senza perdere la navigazione;
andremo a gestire, dal infatti il concetto delle TabBar è proprio creare
codice, la navigazione. differenti linee di vita della nostra applicazio-
Per fare questo creia- ne e permettere una navigazione indiretta che
mo l’azione con nome sarebbe altrimenti difficile.
“premutoPulsante”; Prima di chiudere il progetto, potete anche ag-
in pratica basta aprire giungere un titolo al controller “FirstViewCon-
i file “.m” e “.h” del troller” in modo da renderlo disponibile sulla
“FirstViewController” Navigation Bar e rendere l’applicazione più
ed aggiungere il metodo accattivante e completa; non dimenticate di
necessario alla gestio- andare a fare il “release” di tutti componenti
ne della pressione del che avete utilizzato nell’applicazione, inseren-
Fig. 10 - Esecuzione dell’applicazione pulsante, mediante la do il codice necessario nel metodo “dealloc”

completa delle due “Bar”. IBAction. In un secondo dei controller.

84 Ottobre 2011 ~ Elettronica In


di WALTER DAL MUT e FRANCESCO FICILI
Corso di programmazione iPhone

Corso di programmazione
PUNTATA 6
iPhone

P er concludere il corso
che abbiamo dedica-
to allo sviluppo di ap-
durrà all’utilizzo
del ricevitore GPS
integrato nel telefono.
plicazioni con l’iPhone, Iniziamo con l’accele-
ci occuperemo dell’acce- rometro, che è prodotto
lerometro, spiegandovi dalla ST Microelectro-
come viene configurato nics ed è del tipo a 3
all’interno degli apparati assi, ovvero in grado di
della Apple e proponen- percepire la differenza
do un progetto pratico di velocità su tutti e tre
che ci insegnerà ad gli assi: x,y,z. La mas-
utilizzarlo. Un secon- sima accelerazione che
do progetto pratico ci può sostenere su ciascun
permetterà di utilizzare asse è pari a 3 g. Scopriamo l’accelerometro
un nuovo componente L’accelerometro è uti- ed il ricevitore GPS
per avere un riscontro lizzato come sensore di
di cui l’iPhone è equipaggiato
grafico dell’accelera- base per tutte le applica-
zione cui è sottoposto il zioni, in quanto permet- ed imparando a utilizzarli mediante
dispositivo. Infine, un te di stabilire il senso di due esempi applicativi.
terzo progetto ci intro- orientamento del dispo-

Elettronica In ~ Novembre 2011 69


Corso di programmazione iPhone
Fig. 1 - Assi di orientamento del dispositivo.
sitivo e adeguare, è veramente semplice ed immediato. Dobbiamo
ad esempio, la implementare il protocollo visibile nel Listato 1
visualizzazione; ed attivare l’istanza singolare, come possiamo
ne abbiamo par- vedere nel Listato 2.
lato nella scorsa Dopo aver eseguito questi unici due step, i dati
puntata quando saranno raccolti dal device e la nostra App sarà
abbiamo spiegato sempre aggiornata per la renderizzazione o
le funzionalità l’utilizzo di questi dati.
autorotating ed
autosizing. Utilizziamo l’accelerometro
L’orientamento L’obiettivo del nostro primo progetto pratico
del dispositivo è è realizzare un’applicazione che sia in grado
naturale, ovvero di leggere i dati grezzi dell’accelerometro del
gli assi cartesiani device e renderli disponibili in tempo reale su
immaginari di una view dedicata.
lavoro dell’accele- Per prima cosa avviamo Xcode, creiamo un
rometro sono quelli illustrati nella Fig. 1. nuovo progetto basato su una view e nominia-
In pratica, guardando lo schermo del telefo- molo EIAccelerometer; abbiamo già affrontato
nino girato con il tasto Home verso il basso, questo passaggio nelle precedenti puntate. Una
l’asse orizzontale sono le ascisse, quello vertica- volta fatto ciò, dovremmo essere nella situazio-
le le ordinate e, per finire, l’asse immaginario ne mostrata in Fig. 2.
che punta verso di noi è quello della profondità Xcode ha generato per noi tutti i file necessa-
“z”. Per poter sviluppare applicazioni con ri all’applicazione: le viste, il controller ed il
l’accelerometro è necessario avere la licenza di delegato dell’applicazione. Iniziamo subito ad
sviluppo ed effettuare la sintesi del codice sul elaborare la View, inserendo al suo interno tre
dispositivo. Il simulatore, purtroppo, allo stato etichette e collegandole al codice tramite IB. Per
attuale non è in grado di rendere disponibili fare questo dobbiamo eseguire gli step già visti
dati di accelerazione simulati. nelle puntate precedenti: nel controller inseria-
mo tre oggetti di tipo UILabel e colleghiamoli
Utilizzare l’accelerometro su iPhone ad IB utilizzando il supporto di IBOutlet per
L’accelerometro è modellato tramite un “design queste istanze; non dimentichiamo di andare
pattern singleton”, ovvero è possibile avere una anche ad eseguire la sintesi dei getters e setters,
sola istanza di esso configurata all’interno della tramite la direttiva synthesize. Nella View pos-
nostra applicazione. In aggiunta, per informarci siamo andare ad aggiungere anche tre etichette
sui dati di accelerazione utilizza un “protocollo” completamente statiche, le quali indichino
dedicato molto simile a quello visto per le Ta- all’utente a quale asse si riferisce il dato che sta
bleView, tramite il metodo di callback cellForRo- visualizzando (Fig. 3).
wAtIndexPath, visto nelle prime puntate. Utilizza- A questo punto siamo pronti per introdurre
re questo componente, grazie ai design pattern, l’accelerometro ed attivarlo per la ricezione

Listato 1 - Metodo di call-back per la ricezione dei dati grezzi.


- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration*)acceleration {
//Corpo del codice
}

Listato 2 - Ottenere l’istanza dell’accelerometro e configurare la ricezione.


self.accelerometer = [UIAccelerometer sharedAccelerometer];
self.accelerometer.delegate = self;

70 Novembre 2011 ~ Elettronica In


Corso di programmazione iPhone

Fig. 2 - Iniziamo il progetto per l’accelerometro.

dati. Nel file di intestazione EIAccelerometer- step, nel file oggetto dobbiamo dichiarare, nel
ViewController dobbiamo aggiungere la dichia- corpo, il metodo accelerometer, come mostrato
razione di utilizzo del protocollo UIAccelero- nel Listato 3. A questo punto dobbiamo solo
meterDelegate, necessaria a dichiarare la firma dichiarare l’istanza dell’accelerometro nel
del metodo di ricezione dei dati. Dopo questo file intestazione e configurare il dispositivo

Listato 3 - Metodo di callback utilizzato da cocoa per fornire nuovi dati


- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
//Corpo del metodo.
}

Listato 4 - File di intestazione per il controller principale del progetto.


#import <UIKit/UIKit.h>

@interface EIAccelerometerViewController : UIViewController <UIAccelerometerDelegate>{


UILabel *xAxis;
UILabel *yAxis;
UILabel *zAxis;
}

@property (nonatomic, retain) IBOutlet UILabel *xAxis;


@property (nonatomic, retain) IBOutlet UILabel *yAxis;
@property (nonatomic, retain) IBOutlet UILabel *zAxis;

@property (nonatomic, retain) UIAccelerometer *accelerometer;

@end

Elettronica In ~ Novembre 2011 71


Corso di programmazione iPhone
Fig. 3 - Posizionamento delle etichette nella view di presentazione.

durante il caricamento della vista. Dichiariamo, celerometro. Successivamente ne impostiamo


quindi, un nuovo oggetto di tipo UIAccelerome- la frequenza di aggiornamento di 10 campioni
ter nel file di intestazione e facciamone, come al secondo (0.1 [s]); tipicamente la massima fre-
sempre, la sintesi nel corpo, in modo da poterlo quenza che si riesce ad ottenere con gli iPhone
utilizzare su tutto il nostro controller. 4 è 100 campioni al secondo.
Fatto ciò, il file di intestazione dovrebbe essere In ultima battuta, abbiamo assegnato al de-
simile a quello contenuto nel Listato 4; in legato dell’accelerometro l’istanza del nostro
questo listato non c’è nulla di nuovo, se non la controller, in modo che esso possa avvisarci
direttiva di dichiarazione dell’accelerometro. del nuovo dato in arrivo tramite il metodo di
A questo punto, nel caricamento della vi- callback. Successivamente, il metodo di cal-
sta non dobbiamo fare altro che andare ad lback, chiamato automaticamente, si occupa
inizializzare il componente e, nel metodo di di configurare le nostre etichette presenti sulla
callback, lavorare con le etichette presenti nella vista, introducendo il dato grezzo in arrivo
vista (Listato 5). Nel Listato 5 possiamo vedere dall’accelerometro.
il design pattern singleton alla riga 3, quan- In questo metodo vediamo una chiamata par-
do viene proposta, tramite il metodo statico ticolare: stringWithFormat; essa si occupa di
sharedAccelerometer, l’istanza condivisa dell’ac- restituire una stringa risultato, sulla base di un

72 Novembre 2011 ~ Elettronica In


Corso di programmazione iPhone

Listato 5 - Inizializzazione del componente accelerometro.


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
self.accelerometer = [UIAccelerometer sharedAccelerometer];
self.accelerometer.updateInterval = .1;
self.accelerometer.delegate = self;
}

//... other methods


- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
xAxis.text = [NSString stringWithFormat:@”%f”, acceleration.x];
yAxis.text = [NSString stringWithFormat:@”%f”, acceleration.y];
zAxis.text = [NSString stringWithFormat:@”%f”, acceleration.z];
}

pattern specificato. In questo caso restituisce componente Progress View ed inserirlo tre volte
una stringa per il numero in virgola mobile che nella nostra View. Successivamente, nell’inte-
rappresenta il dato di accelerazione su un asse. stazione del controller andiamo ad inserire le
A questo punto siamo pronti per sintetizzare il dichiarazioni per questi tre nuovi componenti,
nostro codice sorgente direttamente sul device, con la direttiva di IBOutlet per indicare che le
in modo da iniziare a saggiare il funzionamen- utilizzeremo dal codice (Listato 6); una volta
to della nostra applicazione. In Fig. 4 vedete fatto ciò, colleghiamo le dichiarazioni all’in-
la versione in funzione della nostra prima terfaccia grafica (Fig. 5). Ricordiamo anche di
applicazione che utilizza l’accelerometro come andare a realizzare la sintesi dei metodi getters
componente interno. e setters per questi nuovi componenti, tramite
la direttiva di sintesi.
Disegniamo delle barre di accelerazione A questo punto non ci resta che andare ad inse-
Quando si parla di accelerazioni, tipicamente rire il codice necessario, nel metodo di callback
si associa ad esse un’informazione grafica che dell’accelerometro, per far muovere le progress
si muove orizzontalmente per indicare l’ac- bar in relazione alle diverse accelerazioni in
celerazione che si sta subendo su un asse. In gioco.
questa seconda Prima di procedere dobbiamo considerare
esercitazione di che stiamo utilizzando un componente grafi-
progettazione co, tipicamente utilizzato per altri scopi, che
e realizzazione, ammette solo valori positivi, mentre, come
modificheremo sappiamo, le accelerazioni possono determi-
il primo progetto nare anche dati negativi. Perciò eseguiremo
andando ad inseri- l’operazione di modulo sui valori di accelera-
re tre progress bar zione, allo scopo di rendere questi ultimi utili
(UIProgressView) alla visualizzazione su progress bar.
che realizzeranno Il codice del Listato 7 aggiunge al metodo di
una rappresen- callback il controllo tramite codice delle barre
tazione grafica di progresso. Come possiamo vedere, si sono
delle accelerazioni aggiunte tre sole righe. La sintassi è estrema-
sui tre assi. Per mente chiara: stiamo accedendo alla proprietà
prima cosa, nella progress di ogni componente e gli stiamo asse-
vista inseriamo i gnando il valore in modulo, tramite la funzione
tre nuovi compo- ABS, di ogni accelerazione.
nenti: allo scopo A questo punto possiamo avviare la nostra
Fig. 4 - Primo progetto dobbiamo prende- nuova applicazione, in modo da avere anche
con accelerometro in funzione. re, dalla libreria, il un’informazione grafica sulle accelerazioni,

Elettronica In ~ Novembre 2011 73


Corso di programmazione iPhone
Listato 6 - Introduzione delle progress view per le accelerazioni.
#import <UIKit/UIKit.h>

@interface EIAccelerometerViewController : UIViewController <UIAccelerometerDelegate>{


UILabel *xAxis;
UILabel *yAxis;
UILabel *zAxis;

UIProgressView *xProgressView;
UIProgressView *yProgressView;
UIProgressView *zProgressView;
}

@property (nonatomic, retain) IBOutlet UILabel *xAxis;


@property (nonatomic, retain) IBOutlet UILabel *yAxis;
@property (nonatomic, retain) IBOutlet UILabel *zAxis;

@property (nonatomic, retain) IBOutlet UIProgressView *xProgressView;


@property (nonatomic, retain) IBOutlet UIProgressView *yProgressView;
@property (nonatomic, retain) IBOutlet UIProgressView *zProgressView;

@property (nonatomic, retain) UIAccelerometer *accelerometer;

@end

come mostra la Fig. 6; in essa vediamo che te semplice da configurare ed utilizzare, perché
l’accelerometro è un componente estremamen- non ha strutture particolari su cui bisogna agi-

Fig. 5 - Impostazione grafica della nuova interfaccia.

74 Novembre 2011 ~ Elettronica In


Corso di programmazione iPhone

Listato 7 - Il metodo di callback dell’accelerometro modificato per le ProgressView.


- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
xAxis.text = [NSString stringWithFormat:@”%f”, acceleration.x];
yAxis.text = [NSString stringWithFormat:@”%f”, acceleration.y];
zAxis.text = [NSString stringWithFormat:@”%f”, acceleration.z];

self.xProgressView.progress = ABS(acceleration.x);
self.yProgressView.progress = ABS(acceleration.y);
self.zProgressView.progress = ABS(acceleration.z);
}

re. Tuttavia non Introduzione al GPS integrato


dovete sottovalu- Un altro strumento molto interessante all’in-
tare la difficoltà terno dell’iPhone è il ricevitore GPS, che ci
di utilizzare i dati fornisce latitudine, longitudine, altitudine e
che esso fornisce, velocità, tramite il framework dedicato Cocoa
citati nei prece- Touch. Per utilizzare il GPS dobbiamo prima
denti paragrafi aggiungere il framework CoreLocation al no-
con il termine stro progetto. È importante sottolineare che per
“grezzi”, i quali, poter sintetizzare il codice su un device reale,
prima di essere anche in questo caso bisogna avere la licenza di
usati, sarebbe sviluppo.
opportuno che Dunque, apriamo un nuovo progetto basato su
venissero trattati una vista; aggiungere un nuovo framework di
Fig. 6 - Rappresentazione grafica delle
mediante filtri sviluppo è abbastanza semplice: facciamo clic
accelerazioni. digitali. sul progetto intero nella navigation bar a sini-

Fig. 7 - Aggiungere un nuovo framework al progetto.

Elettronica In ~ Novembre 2011 75


Corso di programmazione iPhone
Listato 8 - File di intestazione per l’utilizzo del GPS integrato.
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>

@interface EIGPSViewController : UIViewController <CLLocationManagerDelegate> {


UILabel *latitudeLabel;
UILabel *longitudeLabel;

CLLocationManager *locationManager;
}

@property (nonatomic, retain) IBOutlet UILabel *latitudeLabel;


@property (nonatomic, retain) IBOutlet UILabel *longitudeLabel;

@property (nonatomic, retain) CLLocationManager *locationManager;

@end

stra e poi sui targets apriamo la tab Build Phases zione; allo scopo dobbiamo aggiungere alla
e attiviamo l’accordion Link Binary With Librari- direttiva import l’informazione di inclusione di
es. A questo punto, facendo clic sul tasto + sulla questo nuovo componente. Nella seguente riga
sinistra possiamo aggiungere il framework di codice vediamo un esempio di inclusione
CoreLocation. In Fig. 7 vediamo la situazione per il CoreLocation framework.
relativa all’aggiunta del nuovo sistema.
#import <CoreLocation/CoreLocation.h>
Realizziamo la nostra App
L’obiettivo di questo nuovo progetto è realiz- Ovviamente per framework diversi ci saranno
zare un’App simile a quella già realizzata con importazioni differenti.
l’accelerometro, ma che renda disponibili i Come l’accelerometro, anche il ricevitore GPS
dati di latitudine e longitudine. Per la parte di richiede un metodo di callback per ricevere gli
visualizzazione aggiungiamo le etichette neces- aggiornamenti della posizione, tuttavia può
sarie alla visualizzazione dei dati che andremo anche essere attivato e disattivato, in modo da
a scrivere tramite Xcode (facciamo attenzione ridurre il consumo della batteria.
alle direttive IBOutlet) e successivamente an- Il metodo di callback in questione è dichiarato
diamo a sintetizzare i metodi getters e setters. nel protocollo CLLocationManagerDelegate
Siccome per impostazione predefinita il nuovo insieme a molti altri utili per sfruttare il GPS.
framework non viene utilizzato, per poterlo Prima di tutto dobbiamo dichiarare l’istanza
usare dobbiamo includerlo nei file di intesta- del CLLocationManager in modo da poterla

Listato 9 - Attivazione ed utilizzo del GPS.


- (void)viewDidLoad
{
[super viewDidLoad];

self.locationManager = [[[CLLocationManager alloc] init] autorelease];


self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
}
//... other
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
latitudeLabel.text = [NSString stringWithFormat:@”%f”, newLocation.coordinate.latitude];
longitudeLabel.text = [NSString stringWithFormat:@”%f”, newLocation.coordinate.longitude];
}

76 Novembre 2011 ~ Elettronica In


Corso di programmazione iPhone

Listato 10 - Gestione degli errori per la nostra App.


- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
UIAlertView *errorView = [[UIAlertView alloc] initWithTitle:@”Error” message:[error description] delegate:nil
cancelButtonTitle:@”Chiudi” otherButtonTitles:nil];
[errorView show];
[errorView release];
}

utilizzare nel sviluppatore gestire


controller. Per fare questa casistica.
questo possiamo In questo progetto
inserirla nel file di informiamo l’utente
intestazione, come tramite un’apposita
mostra il Listato 8. finestra di errore.
L’attivazione di Per visualizzare una
questo compo- finestra su iOS possia-
nente è compito mo utilizzare il com-
dell’implemen- ponente UIAlertView,
tazione del il quale realizza già
controller, anch’es- tutte le funzionalità
sa particolarmente richieste. Nel Listato
semplice e che ri- 10 vediamo la realiz-
corda molto quella zazione di una finestra
già effettuata per con il messaggio di
l’accelerometro; errore dedicato.
Fig. 8 - Autorizzazione all’utilizzo va però fatta una Se disabilitiamo Fig. 9 - Latitudine e longitudine
dei dati GPS. precisazione: l’autorizzazione visualizzate sulla nostra applicazione.
l’allocazione del all’utilizzo del GPS
controller è affidata direttamente allo svilup- (tramite le impostazioni generali presenti sul
patore che utilizza un modello autorelease (la device) e riavviamo l’applicazione, questa non
release è effettuata dall’SDK quando il compo- potrà stabilire la nostra posizione; allorà verrà
nente non è più necessario). chiamato il metodo di callback didFailWithError
Nel Listato 9 vediamo le sezioni di codice del CoreLocation framework.
necessarie per l’attivazione del componetente. Una volta ristabilito l’equilibrio assegnando le
Nel metodo viewDidLoad, viene allocato il autorizzazioni, l’applicazione mostrerà la posi-
componente ed inviato il comando di attivazio- zione attuale tramite didUpdateToLocation; ciò è
ne; successivamente, i dati in arrivo sono resi illustrato nella Fig. 9. Quando uno dei parame-
disponibili dal metodo di callback didUpdate- tri del framework varia il nostro metodo, verrà
ToLocation. Il framework CoreLocation mette chiamato informandoci della variazione.
a disposizione molti metodi che si prestano Bene, con questa panoramica sui componenti
all’uso del GPS, tra cui uno per la gestione fondamentali di iOS si conclude la sesta ed
degli errori; proprio la gestione degli errori è ultima puntata del nostro corso di programma-
necessaria in quanto un’applicazione, per poter zione per iPhone.
utilizzare il GPS, deve aver ricevuto l’autoriz- Durante le sei puntate, abbiamo cercato di
zazione dell’utente. farvi conoscere iOS, questo particolare sistema
Se avviamo l’applicazione, vediamo che embedded, fornendovi le basi di programma-
durante il primo avvio viene chiesto di auto- zione orientata agli oggetti e ai design patterns
rizzare l’applicazione (Fig. 8); se l’utente nega e guidandovi alla stesura di alcuni programmi
l’utilizzo del GPS, ciò viene notificato tramite di esempio. Adesso sta ad ognuno di voi farne

il metodo didFailWithError ed è compito dello buon uso.

Elettronica In ~ Novembre 2011 77