Programming iOS lezione 1
-
Upload
nodelay-software -
Category
Technology
-
view
3.070 -
download
3
Transcript of Programming iOS lezione 1
PROGRAMMING IOSSimone Kalb
Chi è iOS?(in numeri)
3° piattaforma mobile venduta al Mondo [IDC]
25% Market share del mercato degli smartphones [IDC]
+0.7% aumento della quota di mercato in un anno [IDC]
16.2M di unità vendute in un anno [IDC]
90M di iPhone vendute con iOS da Giugno 2007 [9to5Mac]
...e questo solo per iPhone!
iOS per iPod Touch e iPad
iPod Touch rappresenta il 38% di tutti i dispositivi con iOS [Ai]
7.3M di iPad venduti dal lancio [WaBR]
Chi è iOS? (a parole)
Un sistema :
operativo moderno per piattaforme mobili e tablet
ideale per gli sviluppatori
fortemente orientato all’interazione gestuale
Chi lo usa?
Tutte le maggiori aziende del settore IT hanno un’app
La maggior parte delle aziende di altri settori
Mercato consumer gigantesco
Comunità di sviluppo fortissima a tutti i livelli
Perché sviluppare per iOS?
Mercato in espansione
API semplici e ottimamente documentate
Opportunità di business
Costi d’ingresso ridicoli
Requisiti
Per sviluppare per iOS è necessario:
Tempo (o una persona che te ne dedichi)(Gratis o quasi...)
Un Mac (da €699,00)
Un device con iOS (da €239,00)
iOS Developer Program (da €79,00)
Totale: da € 917,00
Ambiente di sviluppo
Snow Leopard
Xcode v.3.2.5
Interface Builder
Cosa c’è dentro iOS?Core OS e Core Services
Low-level routines, CFNetwork, CFoundation, SQLite, POSIX
Media Layer
2D, 3D drawing, audio, video, OpenGL ES, Quartz, Core {Audio, Animation}
Cocoa Touch
High level collections, UIKit, GameKit, iAd, MapKit
Cosa vediamo in questo corso?
Configurare l’ambiente di sviluppo
UIKit e IB
View Controller
Navigation Controller
Table View
Tab Controller
Cosa vediamo in questo corso?
MapKit
UIWebView
Parser JSON
API Location
Layar SDK
Xcode
Scarichiamo Xcode da qui (necessaria registrazione gratuita)
Doppio click sull’icona .pkg
Installiamo anche i tools aggiuntivi
Scarichiamo la documentazione per iOS
INTERFACCIA DI XCODEDiamo uno sguardo a come si presenta
Iniziamo con la prima App
File ->New Project (Cmd+Maiusc+N)
View-based-Application
Nominatelo Hello
Build-and-Go
Done!
Primi passi con IB
Aprite HellouserViewController.xib
Trascinate una UILabel nella View
Label Size (cmd+3) portando l’altezza a 80.
Carattere (Cmd+t) a 48
Doppio click e scriviamo “Ciao iPhone”
Salvare e Build-and-Go
RisultatoEcco come appare la nostra app
Rotazione
Hardware -> Rotate Left; Il testo non ruoterà.
IB Finestra d’ispezione (Mela+3).
Strut e spring, attiviamo le springs in tutte e quattro le direzioni.
Specificare anche l’allineamento del testo in maniera che risulti centrato
Modifica al codice
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {// Return YES for supported orientationsreturn YES}
HelloViewController.m
Ora premete Build-and-run
Complimenti avete creato la vostra prima App per iPhone!
Due dritte per i Test
Se siete registrati su ADC come iOS Developer potete:
Creare dei certificati per i dispositivi
Creare dei certificati per gli sviluppatori
Diversi certificati per sviluppatori differenti
Testare le applicazioni su device reali
Nell’editor
Click sulla barra dell’anteprima del file
Potete saltare alla funzione che più vi interessa
Richiamare la documentazione
Passare dal simulatore al device
OBJECTIVE-C
Objective chi?
Sovrainsieme del C di K&R
Ad esso completamente compatibile ed aderente
È un C completamente ad oggetti ma != dal C++
Agli oggetti sono inviati dei messaggi
Il motore di runtime è incaricato dell’invio o meno dei messaggi
Aspetti della sintassi
Parentesi quadre nelle chiamatemioCarattere = [miaStringa characterAtIndex :3];
I parametri hanno sempre un nome e due punti (keyword)
Le classi hanno un file header e uno d’implementazionePersona.m/Persona.h
Tipi di classi
Foundation contiene una serie sterminata di classi di largo uso:
NSString (al posto di char*)
NS{Array, Set, Dictionary}/NSMutable{Array, Set, Dictionary}
NSNumber per numeri di tutti i tipi
UIButton, UITextView,UITableView da UIKit
Organizzazione files in Xcode
Classes
Other Sources
Resources
Frameworks
Products
IBOutlet e IBAction
IBOutlet è una finta “presa” che fa da ponte tra il codice e l’UI
IBAction gestisce le azioni generate dall’interfaccia
Verranno entrambe dichiarate nel file .h e istanziate nel .m@interface HelloUserViewController : UIViewController <UITextFieldDelegate> {!! IBOutlet UILabel *helloLabel;! IBOutlet UITextField *nameField;!
}-(IBAction)sayHello: (id)sender;
Particolarità
IBACtion equivale a void
IBOutlet
IBAction per il pulsante, non c’è bisogno dell’outlet
Pattern (id) sender
Oggetto id
IB Disegnare l’interfaccia
Aprire HelloUserViewController.xib
Vedremo due proxy e una view
Inseriamo una UILabel, una UITextField e un UIButton
Per semplicità la UILabel mettiamola vuota
Nella finestra d’ispezione utilizzare un Placeholder
Nel bottone utilizziamo la dicitura “Dimmi Ciao”
Uno sguardo al File’s Owner
È un proxy alla view
Cliccando col tasto destro si vedono sia gli outlet che le azioni
Ognuno di questi deve essere connesso ad un elemento di UI
In questo caso vedremo helloLabel e nameField
Vedremo la sua importanza nel prosieguo del corso
Connettere gli oggetti
Connettiamo gli oggetti dell’UI con File’s Owner
Ogni oggetto della UI viene connesso con un IBOutlet
Il bottone invece verrà connesso ad un’IBAction
Unire l’evento TouchUp Inside con l’IBAction del File’s Owner
In questo caso l’unica scelta disponibile è sayHello:
Implementazione dell’azione
Adesso implementiamo nel file HelloUserViewController.m-(void) sayHello:(id)sender {!! NSString *username = nameField.text;! NSString *helloMessage = [[NSString alloc] initWithFormat:@"Hello %@", username];! helloLabel.text = helloMessage;! [helloMessage release];! nameField.text = NULL;! [nameField resignFirstResponder];}
Commentiamo il codice
Otteniamo la stringa inserita dall’utente (proprietà)
Instanza di una stringa a cui aggiungiamo “Hello”
%@ è uno specificatore di formato per una stringa di ∀ formato
Impostiamo la proprietà .text per la label con la stringa creata
Ci disfacciamo della stringa non essendo più usata
Reinizializziamo il campo testo della UITextField
Due parole sulle Applicazioni
Diamo uno sguardo a main.m
UiApplicationMain è la funzione principale che si occupa del ciclo di vita dell’applicazione
i due ultimi argomenti sono la classe principale e la sua delegata
La delegata gestisce gli eventi nel ciclo di vita dell’applicazione
In questo caso si carica tutto dai file NIB
Andiamo a vedere i NIB
Apriamo i file MainWindows.xib (come ci suggerisce Info.plist)
Icona di Delegato (HelloUserApp Delegate)
ViewController (HelloUserViewController)
Finestra (UIWindow)
File’s Owner
First Responder
Application, Life Cycle
Il delegato è connesso all’unica finestra dell’applicazione
Il ViewController carica la sua view da un NIB
il primo metodo è applicationDidFinishLaunching:
che carica con callback come initWithCoder: e viewDidLoad:
il primo se caricato il NIB l’altro se caricata la view
La delegationLa delegation è uno dei pattern più importanti dello sviluppo
Un oggetto chiama il suo unico delegato quando si verificano determinati eventi
Dal punto di vista del delegato è una callback
“Chiamami quando succede questo”
Da quello del delegante è uno scarico di responsabilità
“Non so che fare, pensaci tu”
Come funziona un delegato?
Objective-C usa un protocollo di delega formale definito in UIApplicationDelegate
Questo sarebbe come una normale classe
Descrive, però quando i metodi saranno richiamati
Cosa fare quando l’implementatore deve fare quando li richiama
Deve dichiarare che la propria classe implementa il protocollo
Perché tutta questa storia?
Nella nostra app la tastiera non è scomparsa dopo il tap
Il tasto d’invio non ha avuto effetti
Bisogna definire un delegato per il campo di testo
Per la tastiera è necessario lasciare il ruolo di primo risponditore
in sayHello: aggiungiamo la riga:
[nameField resignFirstResponder];
..e per il tasto d’invio?
Esaminiamo la classe delegata UITextFieldDelegate
Dovremo prendere in considerazione textFieldShouldReturn:
Quindi dovremo semplicemente overloadare il metodo
E dire alla classe che implementa UITextFieldDelegate
Modifichiamo il codice
HelloUserViewController.h@interface HelloUserViewController : UIViewController <UITextFieldDelegate> {...}
HelloUserViewController.m-(BOOL)textFieldShouldReturn:(UITextField *)textField{!! [textField resignFirstResponder];! return YES;!}
Ora basta un Build and Run.
Gestione della memoria
La gestione della memoria su device mobili è fondamentale
È necessario appena possibile liberare quanta più memoria
Ogni applicazione per iPhone deve gestirla correttamente
Tutti gli oggetti sono allocati con conteggio riferimenti pari a 1
retain incrementa il conteggio, release lo decrementa
Quando il valore arriva a zero l’oggetto è pronto per il rilascio
Regole d’ingaggio Le regole auree sono:
se siete proprietari d’un oggetto lo dovete rilasciare
se fate new alloc copy, dovrete fare un release
non rilasciate oggetti non vostri
se volete appropriarvene fate un retain
autorelease serve per metodi che restituiscono oggetti non in grado di gestire
Esempio
La NSString ha un metodo stringWithFormat:
Questo è un metodo a rilascio automatico
Non ha alcuna differenza con alloc e initWithFormat:
Questa chiamata non richiede il rilascio dell’oggetto
Rilasciamo gli oggetti
In HelloUserViewController:- (void)dealloc {! [textField release];! [nameField release]; [super dealloc];}
Così siamo sicuri di rilasciare correttamente tutte le variabili in gioco
Le properties
Variabili istanza con nomi che seguono convenzioni in r/w
Accesso a slot per i getter e setter tramite l’operatore punto
[myLabel setText: myString]; - prima
myLabel.text = myString; - dopo
Le properties vanno definite nel file header fuori dalle parentesi
Come si definisce la property
@property (attributi) propType propName;
Vantaggio in termini di leggibilità del codice ma anche:
Gestione della memoria (assign, retain, copy)
Gestione threads (thread-safe, ma nonatomic è più rapido)
@synthesize genera automaticamente i metodi get/set
Modifica del codice
HelloUserViewController.h@property(nonatomic, retain) UILabel *helloLabel;@property(nonatomic, retain) UITextField *nameField;
HelloUserViewController.m@synthesize helloLabel, nameField;
Potremo richiamare helloUserViewController.nameField.text ovunque nel codice anche da altre classi
Ricapitoliamo
Le variabili istanza nel .h
se le inseriamo nel .m gli altri non vi possono accedere
Gli oggetti sono creati nel codice o in IB
Gestite le connessioni con IBOutlets e IBAction in IB
<nomeProtocollo> se volete implementare un delegato on in IB
Dichiarare le properties, sintetizzarle e gestire la memoria
I VIEW CONTROLLER
M V C
Altro paradigma fondamentale in Cocoa
Il View Controller è la “C”
Interagisce con la View (“V”)
Per rappresentare un Modello (“M”) astratto
È un modello sul quale si basa gran parte di quel che vedremo
Apriamo un nuovo progetto
File->New Project
Chiamiamolo Movie
Apriamo MovieViewController.xib
Aggiungiamo un IUButton alla View
Andiamo a modificare il codice
Aggiungiamo una Action
In MovieViewController.h:-(IBAction)done;
Torniamo in IB e facciamo un collegamento tra File’s Owner e il metodo TouchUp Inside
Ora nel file d’implementazione:-(IBAction)done {! NSLog(@"Chiamato il metodo edit"); }
Ora provate a compilare..
Creiamo il modello
Add->New File; Objective-C Class;
Chiamiamola Movie come subclass di NSObject e crea anche il .h@interface Movie : NSObject {
! NSString *title;! NSNumber *boxOfficeGross;! NSString *summary;!}-(id)initWithTitle:(NSString *)newTitle ! boxOfficeGross:(NSNumber *)newBoxOfficeGross! ! summary:(NSString *)newSummary;
@property(nonatomic, copy)NSString *title;@property(nonatomic, copy)NSNumber *boxOfficeGross;@property(nonatomic, copy) NSString *summary;
..e nell’implementazione@implementation Movie
@synthesize title;@synthesize boxOfficeGross;@synthesize summary;
-(id)initWithTitle:(NSString *)newTitle ! boxOfficeGross:(NSNumber *)newBoxOfficeGross! ! summary:(NSString *)newSummary {!! self = [super init];! if(nil != self) {! ! self.title = newTitle;! ! self.boxOfficeGross = newBoxOfficeGross;! ! self.summary = newSummary;! }
! return self;!}
-(void) dealloc {!! self.title = nil;! self.boxOfficeGross = nil;! self.summary = nil;! [super dealloc];!}
@end
Due precisazioni due
self=[super init] serve per gestire i casi in cui la superclasse restituisca oggetti diversi (alcuni FWs lo fanno)
Serve solo in casi di modelli personalizzati
Abbiamo impostato le properties come copy quindi un dealloc è necessario
È buona norma mettere a nil le variabili istanza
La classe ha solo un metodo initWithTitle:
Aggiunta di outlet e azioniNel file MovieViewController.h
#import <UIKit/UIKit.h>
@class Movie;
@interface MovieViewController : UIViewController {!! Movie *movie;! UILabel *titleLabel;! UILabel *boxOfficeGrossLabel;! UILabel *summaryLabel;! MovieEditorViewController *editingViewController;
}
@property(nonatomic, retain) Movie *movie;@property(nonatomic, retain) IBOutlet UILabel *titleLabel;@property(nonatomic, retain) IBOutlet UILabel *boxOfficeGrossLabel;@property(nonatomic, retain) IBOutlet UILabel *summaryLabel;@property(nonatomic, retain) IBOutlet MovieEditorViewController *editingViewController;
-(IBAction)edit;
@end
Da notare come la @class Movie; sia una dichiarazione forward
E nel file .m
Adesso importiamo la classe Movie e sintetizziamo le properties:#import "MovieViewController.h"#import "Movie.h"
@implementation MovieViewController
@synthesize titleLabel;@synthesize boxOfficeGrossLabel;@synthesize summaryLabel;@synthesize movie;
Ora siamo pronti alla modifica dell’interfaccia in IB
Apriamo MovieViewController.xib
Le modifiche all’interfaccia
Nella nostra view inseriamo ben tre UILabel leggermente distanziate
Connettete correttamente gli outlets con le labels
Salvate come al solito IB (altrimenti non succede nulla)
Ritorniamo al codice
Implementiamo il controller in modo che visualizzi di dati
Inizializzazione della View
Non appena si carica la view vogliamo che appaia qualcosa:- (void)viewDidLoad { [super viewDidLoad];! Movie *newMovie = [[[Movie alloc] ! ! ! ! ! ! initWithTitle:@"Iron Man" ! ! ! ! ! ! boxOfficeGross:[NSNumber numberWithFloat:650000000.00]! ! ! ! ! ! summary:@"Un tipo sveglio costruisce armi fighe"] autorelease];! self.movie = newMovie;}
Succede che quando un controller riceve una richiesta vede se ha già una view, in caso contrario carica loadView:
Poi viene richiamato viewDidLoad: non appena visualizzata la view, infine viene chiamato viewWillAppear:
Non appena la view è caricata
Ecco il codice per MovieViewController.m-(void)viewWillAppear:(BOOL)animated {! [super viewWillAppear:animated];! self.titleLabel.text = self.movie.title;! NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];! [formatter setNumberStyle:NSNumberFormatterCurrencyStyle];! self.boxOfficeGrossLabel.text = [formatter stringFromNumber:self.movie.boxOfficeGross];! [formatter release];! self.summaryLabel.text = self.movie.summary;
!}
Il codice aggiunge i dati per gli oggetti Movie nei campi di testo
NSNumberFormatter viene usato per convertire numeri e stringhe
Creazione di un nuovo VC
Scegliete Add->NewFile e scegliete UIViewController Subclass
Ricordatevi di NON spuntare with XIB for user interface
MovieEditorViewController sarà il nome del nuovo VC
Andiamo subito a modificare il codice del controller
Partiamo dall’header file
MovieEditorViewController.h@class Movie;
@interface MovieEditorViewController : UIViewController <UITextFieldDelegate> {
! UITextField *titleField;! UITextField *boxOfficeGrossField;! UITextField *summaryField;! Movie *movie;
}
@property(nonatomic, retain) IBOutlet UITextField *titleField;@property(nonatomic, retain) IBOutlet UITextField *boxOfficeGrossField;@property(nonatomic, retain) IBOutlet UITextField *summaryField;@property(nonatomic, retain) Movie *movie;
-(IBAction)done;
@end
Notiamo che implementiamo l’interfaccia UITextFieldDelegate
E un metodo d’interfaccia per quando avremo finito, done:
MovieEditorViewController.m
Ricordiamoci di aggiungere #import Movie.h; e @synthesize per le proprietà-(void)viewWillAppear:(BOOL)animated {
! [super viewWillAppear:animated];! self.titleField.text = self.movie.title;! self.summaryField.text = self.movie.summary;! NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];! [formatter setNumberStyle:NSNumberFormatterCurrencyStyle];! self.boxOfficeGrossField.text = [formatter stringFromNumber:self.movie.boxOfficeGross];! [formatter release];!}
Notiamo come convertiamo una stringa il numero boxOfficeGross mediante un NSNumerFormatter
MovieEditorViewController.m
Dismettiamo l’attuale view modale per l’azione “Done”-(IBAction)done {! [[self parentViewController] dismissModalViewControllerAnimated:YES];!}
Renderemo in seguito il view controller delegato per ciascun campo di testo in IB
Come prima vedremo come implementare i metodi textFielShouldReturn: e textFieldDidEndEditing:
textFieldShouldReturn:-(BOOL)textFieldShouldReturn:(UITextField *)textField; {
! [textField resignFirstResponder];! return YES;!}
Approfittiamo del momento in cui il controllo rilascia il ruolo di primo risponditore per inserire i dati nell’oggetto:
-(void) textFieldDidEndEditing:(UITextField *)textField {! if(textField == self.titleField) {! ! self.movie.title = self.titleField.text;! } else if(textField == self.boxOfficeGrossField) {! ! NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];! ! [formatter setNumberStyle:NSNumberFormatterCurrencyStyle];! ! self.movie.boxOfficeGross = [formatter numberFromString:self.boxOfficeGrossField.text];! ! [formatter release];! }else if(textField == self.summaryField) {! ! self.movie.summary = self.summaryField.text;! }}
È necessario distinguere i valori digitati nei vari campi
Creazione dell’UIAdd->New File da iOS->User Interfaces e scegliete View XIB
Chiamate il tutto MovieEditorViewController.xib
Cambiamo subito il File’s Owner con MovieEditorViewController
Aggiungete tre campi di testo ed un pulsante
Connettete ciascuno degli outlet dei campi di testo
Connettete infine l’IBAction e i delegati
Tenere sempre presente la tastiera
Pensate sempre alla tastiera che deve apparire per i campi di testo
Password? Numeri? URL? Ad ognuno la sua tastiera
Scegliere l’indicazione corretta del tasto d’invio
L’uso di un segnaposto è talvolta incoraggiato
La funzionalità Clear When Editing Begin va usata con cautela
Creazione del MEVC
Abbiamo quasi finito, ci manca solo come arrivare alla nuova view
I passi da seguire sono i seguenti:
Aggiungere un outlet a MVC per l’istanza di MEVC
Aggiornare il metodo edit:
Creare un’istanza di MEVC nel NIB di MVC e effettuare la connessione
MVC.hIl file MVC.h risulterà ora così:
#import <UIKit/UIKit.h>
@class Movie;@class MovieEditorViewController;
@interface MovieViewController : UIViewController {!! Movie *movie;! UILabel *titleLabel;! UILabel *boxOfficeGrossLabel;! UILabel *summaryLabel;! MovieEditorViewController *editingViewController;
}
@property(nonatomic, retain) Movie *movie;@property(nonatomic, retain) IBOutlet UILabel *titleLabel;@property(nonatomic, retain) IBOutlet UILabel *boxOfficeGrossLabel;@property(nonatomic, retain) IBOutlet UILabel *summaryLabel;@property(nonatomic, retain) IBOutlet MovieEditorViewController *editingViewController;
-(IBAction)edit;
@end
Aggiorniamo edit:Non dimentichiamo di aggiungere l’istruzione #import e i synthesize per ciascuna proprietà.
Il metodo edit: diventerà il seguente-(IBAction)edit {! self.editingViewController.movie = self.movie;! [self presentModalViewController:self.editingViewController! ! ! ! ! ! ! animated:YES];}
Ora aggiungete un view controller al NIB di MVC, impostate MEVC come classe di questo NIB
Infine connettete all’outlet evc del File’s Owner al nuovo VC
Fine!Finalmente l’applicazione dovrebbe essere pronta
Facciamo click su Build and Run
Verifichiamo che l’app funzioni correttamente
In caso contrario scorriamo tutte le proprietà di IB e del codice
In molti casi l’errore s’annida in un riferimento inesistente in IB
Altre volte mancano le dichiarazioni forward o properties non sintetizzate
Compiti per casa
Costruire un’applicazione per il gioco delle 3 carte
La view principale contiene 3 bottoni e un’animazione
Per l’animazione si vede una mano che mescola tre carte
Ogni bottone ti fa accedere ad una view con un’immagine
Se la carta che abbiamo scelto è giusta l’immagine è positiva
Altrimenti è negativa
Dubbi e domandeMetterò online le slide volta per volta
Facciamo un sitarello con Google Sites o equivalente
La mia mail è [email protected]
Rispondo appena posso
La prossima lezione è su Tab Bar e Navigation Controller e MapKit
Scusate per la povertà d’immagini, cercherò di fare meglio..
ALLA SETTIMANA PROSSIMA!