Funzioni nascoste e tips&tricks di OS X

AskDifferent è un po’ lo Yahoo! Answers con argomento Apple. Un filino più tecnico…

In un articolo chiamato “Hidden OS X features or tips and tricks” sono raccolti le funzionalità meno conosciute e i trucchetti più utili del sistema operativo OS X. Anche se non si tratta di argomento iOS, la pagina è così ben fatta che merita una segnalazione.

Launch Images e splash screen

Realizzare una sorta di splash screen per una app è relativamente semplice: basta creare un viewController e caricarlo a tutto schermo prima che la struttura principale appaia, e lasciarla visibile per un certo numero di secondi (2 o 3 potrebbero bastare). La cosa complicata è fare in modo che l’immagine usata per il lancio dell’applicazione (chiamata Launch Images o Default) sia identica e allineata con l’immagine usata per lo splash screen.

Ottenere questo risultato crea una gradevole continuità fra il caricamento dell’app e lo splash screen, dando l’illusione che si tratti della stessa immagine.

Per spiegare come ottenere questo risultato immaginiamo che l’app non si apra a tutto schermo e che quindi bisogna tenere conto della Status Bar, dell’altezza di 20 punti (40 px per i display Retina).

Quindi, una volta create le immagini di Default (320×480, 640×960 e 640×1136), dobbiamo creare le splash images croppando i 20px (o 40px nel caso di display Retina) in cima all’immagine.

Poi nello xib dello splash screen inseriamo una UIImageView a tutto schermo (non importa che interfaccia simuliamo se lasciamo le impostazioni predefinite dei Constraints).

Da codice, nel file .m, basterà indicare quale versione dell’immagine splash usare, a seconda dell’altezza in punti logici del display.

1
2
3
4
5
6
CGRect screenBounds = [[UIScreen mainScreen] bounds];
    if (screenBounds.size.height == 568) {
        self.splashImageView.image = [UIImage imageNamed:@"splash-568h"];
    }else{
        self.splashImageView.image = [UIImage imageNamed:@"splash"];
    }
CGRect screenBounds = [[UIScreen mainScreen] bounds];
    if (screenBounds.size.height == 568) {
        self.splashImageView.image = [UIImage imageNamed:@"splash-568h"];
    }else{
        self.splashImageView.image = [UIImage imageNamed:@"splash"];
    }

Ricordate che @2x per i display Retina non si scrive mai: è il sistema operativo che, se necessario, cercherà l’immagine a risoluzione doppia.

UIActivityIndicator e UINavigationController

Quando si usa un UIActivityIndicator per indicare un caricamento di dati, ad esempio da un server esterno, si può rischiare di non mostrare alcuna rotazione dell’indicatore di attività dal momento che il sistema è molto occupato a caricare i dati.

Inoltre, se ad esempio parliamo di un reloadData di una UITableView con UINavigationController, potrebbe nascere un problema anche quando si preme il tasto Back e dal dettaglio si torna alla tabella principale.

La soluzione è evitare di far girare il metodo startAnimating di UIActivityIndicator nello stesso thread. Questo si può ottenere usando il metodo performSelector con delay 0 secondi:

1
2
3
4
5
6
7
-(void)viewDidAppear:(BOOL)animated{
    
    [super viewDidAppear:animated];
    
    [self.xmlActivityIndicator startAnimating];
    [self performSelector:@selector(reloadXml:) withObject:nil afterDelay:0];
}
-(void)viewDidAppear:(BOOL)animated{
    
    [super viewDidAppear:animated];
    
    [self.xmlActivityIndicator startAnimating];
    [self performSelector:@selector(reloadXml:) withObject:nil afterDelay:0];
}

Inserire questo codice nel metodo viewDidAppear significa garantire che, ogni volta che si entra nella view e che si effettua il pop dell’eventuale dettaglio del navigationController, vengano ricaricati tutti i dati.

URL leggibili per le app

Apple permette l’uso di URL molto leggibili per il collegamento alla pagina iTunes della propria app, o alla pagina relativa allo sviluppatore. In questo modo si può reindirzzare l’utente, su queste pagine, direttamente dall’app. la struttura dei link è la seguente:

  • Nome Compagnia o Sviluppatore
    http://itunes.com/apps/<companyname>
    per esempio http://itunes.com/apps/davidetroise
  • Nome Applicazione
    http://itunes.com/apps/<applicationname>
    per esempio http://itunes.com/apps/familyfinance
  • Applicatione e nome Compagnia (o Sviluppatore)
    http://itunes.com/apps/<companyname>/<applicationname>
    per esempio http://itunes.com/apps/davidetroise/familyfinance

Secondo Nathan S. si possono usare i prefissi itms:// o itms-apps:// al posto di http:// per evitare il redirect passando da Safari.

Selezionare una riga a caso da una tabella SQLite

Succede spesso di utilizzare un database SQLite per una applicazione iOS, e può essere necessario prelevare casualmente una riga da una tabella di questo database (ad esempio in un gioco, in cui la casualità è una componente importante).  Quindi, come recita il titolo, ecco il comando SQLite per selezionare una riga a caso:

1
SELECT * FROM table ORDER BY RANDOM() LIMIT 1;
SELECT * FROM table ORDER BY RANDOM() LIMIT 1;

Nel caso le righe da prelevare fossero più di una, sarebbe sufficiente modificare di conseguenza il limite. Il comando LIMIT, infatti, seleziona le prime n righe dopo che queste sono state casualmente ordinate da comando ORDER BY RANDOM().

Hello, World!

Da poco ho aperto una partita IVA per iniziare la mia attività di sviluppatore di app per iPhone e iPad. Questo blog vuole essere un punto di raccolta di tutte le informazioni utili e interessanti che trovo mentre lavoro alle mie app. Un luogo in cui altri sviluppatori come me possano trovare spunti stimolanti e soluzioni ai problemi che incontreranno. E magari iniziare a collaborare con me a nuovi progetti.

Ma il blog di un programmatore non può non iniziare con un tributo al famoso ”hello, world” di Brian Kernighan e Dennis Ritchie, esempio iniziale del libro “Il Linguaggio C”. Il linguaggio principe per sviluppare per iOS è l’Objective-C, ovvero un elegante cappello Smalltalk per la programmazione ad oggetti messo sulla testa del linguaggio C. Quindi il mio “hello, world” è come quello originario:

1
2
3
main() {
    printf("hello, world\n");
}
main() {
    printf("hello, world\n");
}

Se invece immaginiamo una ipotetica app per iPhone in cui una UILabel, al centro della UIView principale, esponga un testo, allora potremmo scrivere:

1
theLabel.text = @"Hello, World!";
theLabel.text = @"Hello, World!";