Categoria ‘Sviluppo’


iPhone code snippet: UIAlertView

La classe UIAletrView permette di mostrare una finestra modale (animata) per informare e/o chiedere qualcosa all’utente. Le UIAlterView (viste alert) sono molto comode e semplici da usare. Anche la gestione della risposta utente viene risolta intercettando l’indice del bottone premuto. Per visualizzare un semplice UIAlterView basta scrivere:

1
2
3
4
// semplice Alert con un bottone, senza callback
UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:@"Titolo" message:@"Messaggio" cancelButtonTitle:@"Annulla" otherButtonTitles: nil];
[myAlert show];
[myAlert release];

E’ possibile aggiungere ulteriori bottoni in otherButtonTitles:

1
2
3
4
// semplice Alert con due bottoni, senza callback
UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:@"Titolo" message:@"Messaggio" cancelButtonTitle:@"Annulla" otherButtonTitles:@"Ok", nil];
[myAlert show];
[myAlert release];

Per determinare quale bottone è stato premuto, basta aggiungere la delegate:self nell’inizializzazione dell’oggetto UIAlterView:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// semplice Alert con due bottoni e callback
UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:@"Titolo" message:@"Messaggio" delegate:self cancelButtonTitle:@"Annulla" otherButtonTitles:@"Ok", nil];
[myAlert show];
[myAlert release];

// la callback ha questa sintassi

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    switch ( buttonIndex ) {
        case 1:
            // codice
            break;
    }
}

La callback alertView deve avere necessariamente quel nome; per maggiori informazioni vedi UIAlertViewDelegate

Avendo a disposizione solo la callbck alertView:clickedButtonAtIndex, più UIAletrView punteranno sempre a quella. Utilizzando il campo tag dell’oggetto UIAletrView, possiamo determinare quale sia il “chiamante”:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// semplice Alert con due bottoni e callback
UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:@"Titolo" message:@"Messaggio" delegate:self cancelButtonTitle:@"Annulla" otherButtonTitles:@"Ok", nil];
myAlertA.tag = 1;
[myAlertA show];
[myAlertA release];

//
UIAlertView *myAlertB = [[UIAlertView alloc] initWithTitle:@"Titolo" message:@"Messaggio" delegate:self cancelButtonTitle:@"Annulla" otherButtonTitles:@"Ok", nil];
myAlertA.tag = 2;
[myAlertB show];
[myAlertB release];

// gestione multipla UIAlertView

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    NSLog(@"Alert Tag: %i", alertView.tag);
    NSLog(@"buttonIndex: %i", buttonIndex);
}

Continua...

iPhone Objective-C: equivalenza nella sintassi

La sintassi con le parentesi quadre in Objective-C è uno dei motivi di maggior frustazioni per chi proviene da altri linguaggi (ad oggetti). Tuttavia, fatta l’abitudine, ci si rende conto di quanto il codice diventi ugualmente leggibile con questa il mix della sintassi classica e quella più spiccatamente Smalltalk. Ad esempio vediamo come la stessa procedura può essere scritta in entrambe le sintassi. Prendiamo l’inizializzazione di un UIAlertView:

1
2
3
4
5
6
7
8
UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:@"Titolo"
                                            message:@"Messaggio"
                                            delegate:self
                                            cancelButtonTitle:@"Annulla"
                                            otherButtonTitles:@"Ok",nil];
myAlert.tag = 1;
[myAlert show];
[myAlert release];

L’impostazione del tag potavamo farla anche così:

1
2
3
4
5
6
7
8
UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:@"Titolo"
                                            message:@"Messaggio"
                                            delegate:self
                                            cancelButtonTitle:@"Annulla"
                                            otherButtonTitles:@"Ok",nil];
[myAlert setTag:1];
[myAlert show];
[myAlert release];

Stessa cosa in lettura durante l’evento:

1
2
3
4
5
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    if( alertView.tag == 1 ) { // ...
    // oppure
    if ([alertView tag] == 1) { // ...
}

Nota bene: non tutte le proprietà o metodi hanno questa duplice sintassi. Nel caso dell’UIAlertView abbiamo questa doppia funzionalità. Per altri oggetti o in altri casi, invece, potrebbero funzionare una sola delle due… ma non chiedetevi perchè (dipende da come gli sviluppatori hanno definito l’interfaccia).

Continua...

Actionscript trace, Objective-C NSLog()

Riprendendo il post Da Actionscript ad Objective-C (dove si mettevano a confronto il codice e la sintassi Actionscript e Objective-C), in Actionscript abbiamo la comodissima funzione trace(), usata per il debug delle applicazioni. Questa funzione emette un output sulla console dell’ambiente di sviluppo Adobe Flash. Viene utilizzata principalmente nelle fasi di sviluppo e testing di “filmato”/applicativo. In XCode/Objective-C abbiamo: NSLog(). La sintassi di questa funzione è molto simile alla trace() di Actionscript:

1
NSLog( @"Sono una linea di debug" );

In Actionscript avremmo:

1
trace( "Sono una linea di debug" );

A parte l’uso della chiocciola (@), come potete vedere, sono identiche. Le differenze (e similitudini) iniziano quando si vogliano visualizzare valori di variabili; ad esempio in Actionscript potremmo avere:

1
2
3
trace( "Coordinata x:" + x + " coordinata y:" + y );
// oppure
trace( "Coordinate: ", x, y );

In Objective-C abbiamo:

1
NSLog( @"Coordinata x:%i coordinata y:%i", x, y );

Nota: NSLog() in realtà richiama la più generica funzione NSLogv() che opera sull’Apple System Log. Le funzioni sono di fatto identica, cambiano solo i parametri in ingresso.

Gli sviluppatori C troveranno molto familiare la formattazione delle stringhe, come accade per printf() o sprintf(). Per dettagli si veda String Format Specifiers.

Continua...

Very short trick: fermare NSTimer

L’uso dei timers (NSTimer) nello sviluppo di applicazioni per Apple iPhone è molto frequente e non solo nella realizzazione di giochi. Uno dei problemi con cui ci si può scontrare è l’asincronicità del timer stesso, che può portare, durante l’arresto di uno o più timer, al crash della nostra applicazione. Quando si vuole fermare uno o più timer, nei casi in cui repeats è impostato a YES, si invoca la invalidate che, appunto, arresta il timer.

Continua...

Apple iPhone SDK 3.0: risolto baco su UIButton buttonWithType

Come indicato nel post Apple iPhone SDK 3.0: prime incompatibilità le SDK 3.0 di Apple mostrano comportamenti differenti rispetto alla release 2.2.1. Il supporto di assistenza per gli sviluppatori mi ha fornito la risposta, e quindi la soluzione al problema. La risposta del supporto tecnico è stata che [UIButton buttonWithType:] già chiama – al suo interno – la initWithFrame. Ne deriva che, sempre secondo il supporto tecnico, scrivendo:

Continua...

Da Actionscript ad Objective-C

Ho pensato che potrebbe essere utile a chi si è avvicinato da poco allo sviluppo di applicazioni per Apple iPhone, confrontare Adobe Actionscript – il linguaggio utilizzato in Adobe Flash e Adobe Flex, più diffuso tra i neo-programmatori – e Objective-C, il linguaggio utilizzato da Apple per sviluppare le sue applicazioni. Objective-C è a tutti gli effetti un linguaggio ad oggetti nel senso puro, non che Actionscript non lo sia, ma Objective-C ha sicuramente una marcia in più in quanto è un’estensione dell’ANSI C e la sua sintassi è un mix tra C/C++ e Smalltalk; è un vero OO (Object-oriented language).

Continua...

Apple iPhone SDK 3.0: prime incompatibilità

Dopo aver installato le SDK 3.0 per Apple iPhone, evidentemente ancora non perfettamente stabili, ho subito riscontrato alcuni problemi, sia nella compilazione del codice sia nell’impostazione generale di XCode. Il più importante – che ho prontamente segnalato con un “case” ad Apple, al centro sviluppatori – riguarda la creazione di bottoni tramite codice. Ecco un estratto del codice non compatibile con le SDK 3.0:

1
2
3
4
UIButton *myButton = [[UIButton buttonWithType:UIButtonTypeRoundedRect] initWithFrame:CGRectMake(0, 0, 100, 40)];
[myButton setTitle:@"Bottone" forState:UIControlStateNormal];
// altre impostazioni
[self.view addSubview:myButton];

Compilando questo codice con le SDK 2.2.1 si ottiene un classico bottone con la label “Bottone”. Con le SDK 3.0 il bottone viene creato ma la label scompare. Utilizzando come buttonWithType il tipo UIButtonTypeCustom la situazione sembra migliorare, nel senso che la label viene resa apparentemente in modo corretto. Rimane comunque strano l’improvviso malfunzionamento sul tipo UIButtonTypeRoundedRect. Sono ancora in attesa di una risposta da Apple… appena ho novità; posto!

Continua...

The First: disponibile su iTunes

Sei giorni ed AppStore ha approvato la (mia) prima applicazione per Apple iPhone!

Continua...

iPhone: l’utilissima proprietà tag

Tutti gli oggetti che derivano dalla classe <a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/cl/UIView">UIView</a>, ereditano l’utilissima proprietà <a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/doc/uid/TP40006816-CH3-SW25">tag</a>. Questa proprietà è un vero e proprio user-data (un “posto” che lo sviluppatore usa per usi generici) di tipo <a target="_blank" href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_DataTypes/Reference/reference.html#//apple_ref/doc/c_ref/NSInteger">NSInteger</a>, dove quindi possiamo memorizzare esclusivamente numeri.

L’uso che se ne può fare dipende ovviamente dalle circostanze tuttavia risulta utilissimo per individuare un determinato oggetto allo scattare di un evento comune. Ad esempio immaginiamo di avere due <a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIAlertView_Class/UIAlertView/UIAlertView.html">UIAlertView</a> che rispondono allo stesso evento:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// primo alert
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Primo" message:@"Primo Alert" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil,nil];
[alert show];
[alert release];

// ...

// secondo alert
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Secondo" message:@"Secondo Alert" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil,nil];
[alert show];
[alert release];

// Evento
// Cliccandi sul bottone OK degli Alter verrà chiamata questa funzione
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    // todo
}

Nota: negli esempi di codice troverete l’indicazione C++. Questo non è del tutto corretto in quanto, come saprete, il linguaggio usato è Objective-C. Questo a causa del fatto che il Plugin che uso per visualizzare il codice sorgente non supporta Objective-C, e il C++ è quello che meglio gli si avvicina.

Come distinguere i due Alert? Utilizzando appunto la proprietà tag. Dopo la creazione dell’oggetto alert basta inserire:

1
2
3
4
5
6
7
8
9
10
11
12
13
// primo alert
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Primo" message:@"Primo Alert" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil,nil];
[alert setTag:1]; // imposto il tag di questo Alert ad 1
[alert show];
[alert release];

// ...

// secondo alert
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Secondo" message:@"Secondo Alert" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil,nil];
[alert setTag:2]; // imposto il tag di questo Alert ad 2
[alert show];
[alert release];

Ora modifichiamo l’evento in modo da capire quale Alert è stato chiuso:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Evento
// Cliccandi sul bottone OK degli Alter verrà chiamata questa funzione
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    switch (alertView.tag) {
        case 1:
            // Primo Alert
            break;
        case 2:
            // Secondo Alert
            break;
        default:
            break;
    }
}

Stessa identica tecnica può essere utilizzata se abbiamo una serie di <a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIButton_Class/UIButton/UIButton.html">UIButton</a> creati runtime. Ad esempio:

1
2
3
4
5
6
7
8
9
10
for( unsigned int i=0; i < 10; i++) {
    UIButton *mybutton = [[UIButton buttonWithType:UIButtonTypeCustom] initWithFrame:CGRectMake(i*20, i*20, 20, 20)];
    [mybutton setTitle:@"But" forState:UIControlStateNormal];
    [mybutton setTag:i]; // imposto il tag

    // stesso evento per tutti
    [mybutton addTarget:self action:@selector(onTouchUpInside:) forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:mybutton];
}

Nell’evento onTouchUpInside recuperiamo dal sender (dove eseguiamo un casting <a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/cl/UIView">UIView</a>) la proprietà <a target="_blank" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/doc/uid/TP40006816-CH3-SW25">tag</a>:

1
2
3
4
-(void)onTouchUpInside:(id)sender {
    unsigned int button_tag = ((UIView *)sender).tag;
    // todo
}

Continua...

Very short snippet: visualizzare una lista di post per categoria o tag

Due funzioni utili, personalizzabili a piacere, da usare per mostrare gli ultimi n post di una categoria o per uno o più tag. Le funzioni, come vedrete, sono molto simili e si basano entrambe su un loop generato tramite query_post(). La prima, show_title_cat(), mostra gli ultimi post (in questa versione solo il titolo) di una determinata categoria:

Continua...



Stop SOPA