Semplice modo per salvare nell’album fotografico del dispositivo un’immagine presente all’interno della nostra applicazione (o caricata da remoto):
Categoria ‘Objective-C’
Very short snippet: registrare un’immagine nel Photo Album
NSURLConnection: esempio d’uso
NSURLConnection permette di eseguire una connessione cotrollata verso un server remoto. Per utilizzarlo basta:
1 2 3 4 5 6 7 8 9 10 11 | // Gli oggetti sufficienti per eseguire una NSURLConnection NSURLConnection *urlConnection; NSMutableData *mutableData; // ... NSString *urlString = @"http://www.miodominio.com/documento.txt"; NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString: urlString]]; // Il delegato risponderà agli stati della connessione urlConnection = [[NSURLConnection alloc] initWithRequest: urlRequest delegate:self]; |
Ecco i metodi delegati per controllare lo stato della connessione:
[cc_objc]
Very short snippet: Objective-C, Selector from NSString
Objective-C è un linguaggio meraviglioso che permette di fare cose incredibili. Uno degli aspetti più interessanti è la sua dinamicità nell’invocazione di metodi (messaggi). È possibile, infatti, ottenere l’indirizzo di un messaggio partendo da una stringa.
Very short snippet: UIWebView, visualizzare PDF e file interni
L’oggetto UIWebView può essere utilizzato per la visualizzazione di numerosi file. Ad esempio è possibile utilizzarlo per visualizzare – oltre che a filmati QuickTime o YouTube – documenti PDF o file HTML inseriti all’interno del nostro codice.
NSString
NSString è una classe potentissima, lasciatemi mostrare alcune delle proprietà più utilizzate:
printf()
Eseguire lo split()
1 2 3 |
Convertire da stringa a valore
1 2 3 |
All’interno di una stringa
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // substring NSString *searchString = @"age"; NSString *beginsTest = @"Agencies"; NSRange prefixRange = [beginsTest rangeOfString:searchString options:(NSAnchoredSearch | NSCaseInsensitiveSearch)]; // prefixRange = {0, 3} NSString *endsTest = @"BRICOLAGE"; NSRange suffixRange = [endsTest rangeOfString:searchString options:(NSAnchoredSearch | NSCaseInsensitiveSearch | NSBackwardsSearch)]; // suffixRange = {6, 3} |
Very short snippet: comporre mail all’interno di un’applicazione iPhone, iPod o iPad
Per comporre email all’interno di una applicazione iPhone/iPod è sufficiente aggiungere il framework MessageUI. Nel nostro controller inserire l’inclusione del framework e adottare il protocolo MFMailComposeViewControllerDelegate:
Objective-C: metodi di classe e auto alloc
Quando definiamo o utilizziamo metodi (messaggi) in ambiente Objective-C, ci troviamo spesso di fronte alla curiosa sintassi che si presenta con un simbolo - o + davanti al prototipo, tipo:
1 2 3 4 5 6 7 | // Nella definizione - (void)mioMessaggio; // Ugualmente, nell'implementazione - (void)mioMessaggio { // ... } |
Oppure:
1 2 3 4 5 6 7 | // Nella definizione + (void)mioMessaggio; // Ugualmente, nell'implementazione + (void)mioMessaggio { // ... } |
La differenza risiede nel fatto che i metodi definiti con il simbolo - sono metodi di instanza, legati quindi ad un oggetto. I metodi definiti con il simbolo + sono chiamati metodi di Classe, in quanto possono essere eseguiti senza allocare ed istanziare l’oggetto in questione.
NSString o UIView sono due classi, molto usate, che contengono svariati metodi di classe. I metodi di classe vengono utilizzati continuamente, come quando inizializziamo o allochiamo un qualsiasi oggetto:
1 | UIView *myView = [UIView alloc]; |
Il metodo alloc è un esempio classico, presente in tutti gli oggetti e, come si evince dal codice, è un metodo di classe in quanto invocato prima dell’allocazione dell’oggetto vero e proprio.
I metodi di classe possono essere utili in moltissimi casi, in particolare quando creiamo un nostro oggetto e desideriamo allocarlo ed inizializzarlo in meno righe di codice possibile. Immaginiamo di dover collezionare in un array una serie di oggetti da noi definiti. Definiamo prima di tutto il nostro oggetto, scrivendo il codice nel modo più semplice, senza utilizzare metodi di classe:
1 2 3 4 5 6 7 8 9 10 |
L’implementazione, nel caso più semplice, potrebbe risultare nulla o:
1 2 3 4 5 6 7 8 9 10 11 12 | // myObject.m #import "myObject.h" @implementation myObject @synthesize name, lastname; - (void)dealloc { [name release]; [lastname release]; [super dealloc]; } |
Quando andremo ad usare il nostro oggetto, ci troveremo ad utilizzare un codice simile a questo:
1 2 3 | myObject *obj = [myObject alloc]; obj.name = @"Mario"; obj.lastname = @"Rossi"; |
Se volessimo creare numerosi oggetti di questo tipo, e inserirli in un NSArray, la situazione diventa un poco imbarazzante:
1 2 3 4 5 6 7 8 9 10 11 12 |
Si potrebbe migliorare il codice creando un ciclo for o utilizzando un NSMutableArray per aggiungere man mano gli oggetti nel nostro elenco. Tuttavia la situazione migliorebbe di poco, in quando rimarrebbero fuori le impostazioni delle proprietà name e lastname. Verrebbe quindi spontaneo, per iniziare, aggiungere un metodo – di oggetto – initWithName che consentirebbe di passare immediatamente le impostazioni delle proprietà, semplificandoci un pochino le cose. Nel file di implementazione myObject.m aggiungiamo:
1 2 3 4 5 6 7 |
Così facendo abbiamo migliorato la situazione, potendo ora scrivere:
1 2 3 4 5 6 7 |
Abbiammo tuttavia ancora i puntatori objA e objB, necessari per l’inserimento nell’array e liberare la memoria. Volendo potremmo inserire direttamente la creazione di un oggetto nel popolamento dell’array, utilizzando autorelease per liberare la memoria, ma il codice sarebbe ancora non al minimo. Lasciatemi mostrare come risolvere la questione con un metodo di classe. Prima di tutto sostituiamo la nostra - (id)initWidthName con:
1 2 3 4 5 6 7 8 9 10 |
Così facendo abbiamo creato un metodo di classe che alloca (in autorelase) e iniziallizza un nostro oggetto, prima di avere il puntatore all’istanza. Il codice di utilizzo diventa quindi:
1 2 3 4 |
Molto, molto meglio…
iPad: gestire le schermate d’avvio
Su Apple iPhone e iPod eravamo abituati a gestire un solo file immagine al caricamento dell’applicazione, il file Default.png. Su Apple iPad, invece, la diversa gestione dell’orientamente impone l’adozione di più file immagine, per essere certi di visualizzare lo splash screen corretto in base all’orientamente del dispositivo. Durante l’avvio dell’applicazione, come accadeva per iPhone, non è infatti possibile intervenire da codice per “chiedersi” com’è orientato il dispositivo. Fortunatamente è stato introdotto in automatico il caricamento di speciali file a seconda dell’orientamento:

I file attualmente supportati, oltre al classico Default.png che sconsiglio di utilizzare in quanto viene ridimensionato e deformato in base all’orientamento, sono:
- Default-Portrait.png
- Default-PortraitUpsideDown.png
- Default-Landscape.png
- Default-LandscapeLeft.png
- Default-LandscapeRight.png
Le versioni PortraitUpsideDown, LandscapeLeft e LandscapeRight possono essere utilizzate per determinare orietamento e verso di quest’ultimo.
Ad applicazione avviata, poi, come consigliato da Apple, è bene “ridisegnare” – ove necessario – le nostre viste agendo all’interno di application:didFinishLaunchingWithOptions.
Personalizzare le sezioni in un UITableView Grouped
Quando utilizziamo una UITableView in stile Grouped potremmo aver necessità di personalizzare la grafica dei titoli delle sezioni, come California o New York dell’esempio qui sotto.

Per farlo basta utilizzare il codice seguente, inserendolo nel delegato, cioè nella classe che risponde al protocollo UITableViewDelegate:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // Restituisco una mia View personalizzata, in questo caso un oggetto // di tipo UILabel - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { UILabel *label = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease]; label.font = [UIFont boldSystemFontOfSize:20]; label.textAlignment = UITextAlignmentCenter; label.shadowColor = [UIColor blackColor]; label.shadowOffset = CGSizeMake(1, 1); label.text = @"Sezione"; // Sostituire con un array come al solito label.textColor = [UIColor whiteColor]; label.backgroundColor = [UIColor clearColor]; label.opaque = NO; return label; } // Bisogna supportare anche questo message altrimenti non funziona - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { return 44; } |
È importante inserire anche heightForHeaderInSection, altrimenti non funziona.
Note interessanti
Nella creazione della nostra UILabel, che volendo potrebbe essere anche un oggetto più complesso come una UIView o UIImageView, ho utilizzato per inizializzare il frame CGRectZero che corrisponde a CGRectMake(0,0,0,0).
Come ottenere Latitudine e Longitudine in Objective-C
Il MapKit framework fornisce moltissime funzionalità utili, tranne quella di restituire Longitudine e Latitudine a partire da un indirizzo. In Javascript, ad esempio, è possibile utilizzare il servizio di Geocoding fornito da Google e discusso in Google Maps: come ottenere Latitudine e Longitudine da un indirizzo. Su Apple iPhone, o iPad, è possibile tuttavia superare l’ostacolo utilizzando in modo diverso i servizi di Google. Nello specifico è possibile chiamare direttamente l’url:
1 | http://maps.google.com/maps/geo?q=[indirizzo]&output=csv |
Dove è [indirizzo] inserire la stringa con l’indirizzo che vogliamo trasformare in coordinate. L’output restituito è del tipo:
1 | 200,8,41.9128300,12.2241172 |
Il primo valore, 200, indica che tutto è andato bene (200 OK). Il secondo, 8, è il Google accuracy parameter (1-10). Gli ultimi due valori sono, finalmente, latitudine e longitudine. Vediamo adesso un possibile prototipo di un metodo da inserire nelle nostre applicazioni:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | - (CLLocationCoordinate2D)getLocationFromAddress:(NSString*)address { NSString *urlString = [NSString stringWithFormat:@"http://maps.google.com/maps/geo?q=%@&output=csv", [address stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]; NSString *locationString = [[[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:urlString]] autorelease]; NSArray *listItems = [locationString componentsSeparatedByString:@","]; //int zoom = 0; double latitude = 0.0; double longitude = 0.0; if([listItems count] >= 4 && [[listItems objectAtIndex:0] isEqualToString:@"200"]) { //zoom = [[listItems objectAtIndex:1] intValue]; latitude = [[listItems objectAtIndex:2] doubleValue]; longitude = [[listItems objectAtIndex:3] doubleValue]; } else { // Errore } CLLocationCoordinate2D location; location.latitude = latitude; location.longitude = longitude; return location; } |
Note interessanti
La stringa restituita in locationString viene “splittata” tramite il metodo componentsSeparatedByString, alla stregua della funzione explode() del PHP per intenderci. Nell’esempio da me proposto ho inserito – ma commentato – il codice per recuperare anche il Google accuracy parameter, o fattore di scala di precisione, indicato con zoom.
Sorgente esempio
Per completezza ho realizzato un piccolo applicativo di esempio con il quale è possibile provare il metodo sopra proposto; inserite un qualsiasi indirizzo e iPhone lo mostrerà sulla mappa.
Ringrazio il team di devAPP per l’ispirazione di questo articolo.







Ultimi Commenti
Marco: Ti ringrazio moltissimo, mi hai illuminato
ho risolto impostando [cc_objc] //OptionViewController.m -...
Giovambattista Fazioli: @Marco: Ti consiglio un approccio credo più corretto. Se hai eseguito il subclass del tab...
Marco: Scusa lo spam.. ho notato che c’è un errore.. ecco la correzione [cc_objc] /** PrimaClasse.h **/ #import...
Marco: dimenticato.. in [cci]OptionViewController[/cci ] il [cci]@syntetize[/cci] del delegato l’ho messo
luigi: molto chiaro e semplice devo ammettere che anche scrivendo da un pà difficilmente uso delegati creati da...