SlideShare ist ein Scribd-Unternehmen logo
1 von 80
Downloaden Sie, um offline zu lesen
SVILUPPO APP CON IOS
        Simone Kalb
E tu chi sei?

Mi chiamo Simone Kalb

Socio del GulCh

Junior Software Developer at CRS4 (Open Media Center Lab)

System Administrator

GNU/Linux e MacOS X avid user
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 venduti 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


Leopard (10.5)/Snow Leopard (10.6)/Lion (10.7) Beta

Xcode v.3.2.5/Xcode v.4.0.2/Xcode 4.2 (Beta)

Interface Builder (compreso con Xcode)

Eventualmente documentazione reperibile su http://bit.ly/
mqPaHf
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 quest’oggi?
L’ambiente di sviluppo

Una semplice applicazione

  Objective-C

  Classi

  IBOutlet e IBAction

  File’s Owner
Cosa vediamo in questo corso?
Connessione di oggetti

Struttura delle applicazioni

I files XIB

La delegation

La gestione della Memoria

Properties
Cosa vediamo in questo corso


I view Controller

Il pattern MVC

Esempietto finale
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 XCODE
     Diamo 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
Risultato
Ecco 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
HelloViewController.m
 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)
 interfaceOrientation {
 // Return YES for supported orientations
 return YES
 }


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 chiamate
mioCarattere = [miaStringa characterAtIndex :3];


I parametri hanno sempre un nome e due punti (keyword)

Le classi hanno un file header e uno d’implementazione
Persona.m/Persona.h


Altro codice utile può essere importato con import nel file header
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

  NSURL che contiene wrapper per file:// e http:// e alt.
Organizzazione files in Xcode

Classes

Other Sources

Resources

Frameworks

Products
Modifichiamo la nostra App

Chiudiamo il nostro progetto precedente e creiamone un altro

Anche questa volta scegliamo View-Based Application

Chiamiamolo HelloUser

La nostra App saluterà l’utente col il suo nome precedentemente
scritto
Cosa dobbiamo fare?

Dobbiamo creare una label per visualizzare il messaggio

Un campo di testo per il nome dell’utente

Un pulsante per accettare l’input

Un metodo che aggiorni l’etichetta di testo una volta premuto il
pulsante
Connessioni
Per fare ciò che abbiamo descritto è necessario

  Istruire l’interfaccia grafica con gli elementi

  Istruire il codice con i metodi appropriati

  Un riferimento dal codice alla UI si chiama outlet

  Per definire un oggetto del genere si ricorre ad IBOutlet

  Per ogni azione, invece, si usa IBAction
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

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 nella UIText

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
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 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 delegation
La 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
MVC

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 ->View-Based Application

Chiamiamolo Movie

Apriamo MovieViewController.xib

Aggiungiamo un UIButton 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 azioni
       Nel 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’UI
Add->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.h
       Il 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
Prima di terminare


Alcuni riferimenti

  Twitter @simonekalb

  LinkedIn Simone Kalb

  email: simone@nodelay.org
Prima di concludere (ancora..)

Un ringraziamento speciale al Java User Group Sardegna
ONLUS e a Massimiliano Dessì

Un altro ringraziamento particolare a tutti voi che siete
intervenuti qui stasera

Le slides sono disponibili su SlideShare

Per qualsiasi altra cosa chiedete pure..
QUESTION TIME
THE END!

Weitere ähnliche Inhalte

Ähnlich wie Sviluppo Di Applicazioni Su I Os

Wearable Lab: Progettazione per Apple Watch
Wearable Lab: Progettazione per Apple WatchWearable Lab: Progettazione per Apple Watch
Wearable Lab: Progettazione per Apple WatchPaolo Musolino
 
Progettazione per Apple Watch - Todi Appy Days 2015
Progettazione per Apple Watch - Todi Appy Days 2015Progettazione per Apple Watch - Todi Appy Days 2015
Progettazione per Apple Watch - Todi Appy Days 2015Todi Appy Days
 
Xcode - Just do it
Xcode - Just do itXcode - Just do it
Xcode - Just do itpragmamark
 
Sviluppare app native per iOS
Sviluppare app native per iOSSviluppare app native per iOS
Sviluppare app native per iOSGaspare Novara
 
Sviluppare apps native per iOS - Lo Stretto Digitale
Sviluppare apps native per iOS - Lo Stretto DigitaleSviluppare apps native per iOS - Lo Stretto Digitale
Sviluppare apps native per iOS - Lo Stretto Digitalelostrettodigitale
 
Sviluppo apps multipiattaforma con visual studio e xamarin
Sviluppo apps multipiattaforma con visual studio e xamarinSviluppo apps multipiattaforma con visual studio e xamarin
Sviluppo apps multipiattaforma con visual studio e xamarinFabio Cozzolino
 
Meetup ASP.NET Core Angular
Meetup ASP.NET Core AngularMeetup ASP.NET Core Angular
Meetup ASP.NET Core Angulardotnetcode
 
Introduzione alla programmazione android - Android@tulug lezione 2
Introduzione alla programmazione android - Android@tulug lezione 2Introduzione alla programmazione android - Android@tulug lezione 2
Introduzione alla programmazione android - Android@tulug lezione 2Ivan Gualandri
 
FROM A TO C(HECK-IN): iOS e Swift Lab
FROM A TO C(HECK-IN): iOS e Swift LabFROM A TO C(HECK-IN): iOS e Swift Lab
FROM A TO C(HECK-IN): iOS e Swift LabPaolo Musolino
 
Introduzione a Node.js
Introduzione a Node.jsIntroduzione a Node.js
Introduzione a Node.jsMichele Capra
 
Ionic Cordova vs React Native
Ionic Cordova vs React NativeIonic Cordova vs React Native
Ionic Cordova vs React NativeAntonio Gallo
 
MOBILE APPS con ANDROID - Lo Stretto Digitale
MOBILE APPS con ANDROID  - Lo Stretto DigitaleMOBILE APPS con ANDROID  - Lo Stretto Digitale
MOBILE APPS con ANDROID - Lo Stretto Digitalelostrettodigitale
 
Webkit meets native development
Webkit meets native developmentWebkit meets native development
Webkit meets native developmentNicholas Valbusa
 
ios 8 - parte 1 - intro - ita
ios 8 - parte 1 - intro - itaios 8 - parte 1 - intro - ita
ios 8 - parte 1 - intro - itaDario Rusignuolo
 
Modi innovativi per costruire App
Modi innovativi per costruire AppModi innovativi per costruire App
Modi innovativi per costruire AppCommit University
 

Ähnlich wie Sviluppo Di Applicazioni Su I Os (20)

Wearable Lab: Progettazione per Apple Watch
Wearable Lab: Progettazione per Apple WatchWearable Lab: Progettazione per Apple Watch
Wearable Lab: Progettazione per Apple Watch
 
Progettazione per Apple Watch - Todi Appy Days 2015
Progettazione per Apple Watch - Todi Appy Days 2015Progettazione per Apple Watch - Todi Appy Days 2015
Progettazione per Apple Watch - Todi Appy Days 2015
 
Xcode - Just do it
Xcode - Just do itXcode - Just do it
Xcode - Just do it
 
Sviluppare app native per iOS
Sviluppare app native per iOSSviluppare app native per iOS
Sviluppare app native per iOS
 
Sviluppare apps native per iOS - Lo Stretto Digitale
Sviluppare apps native per iOS - Lo Stretto DigitaleSviluppare apps native per iOS - Lo Stretto Digitale
Sviluppare apps native per iOS - Lo Stretto Digitale
 
Sviluppo apps multipiattaforma con visual studio e xamarin
Sviluppo apps multipiattaforma con visual studio e xamarinSviluppo apps multipiattaforma con visual studio e xamarin
Sviluppo apps multipiattaforma con visual studio e xamarin
 
Meetup ASP.NET Core Angular
Meetup ASP.NET Core AngularMeetup ASP.NET Core Angular
Meetup ASP.NET Core Angular
 
Xcode - Just do it
Xcode - Just do itXcode - Just do it
Xcode - Just do it
 
Spiegazione Programma phone
Spiegazione Programma phoneSpiegazione Programma phone
Spiegazione Programma phone
 
Introduzione alla programmazione android - Android@tulug lezione 2
Introduzione alla programmazione android - Android@tulug lezione 2Introduzione alla programmazione android - Android@tulug lezione 2
Introduzione alla programmazione android - Android@tulug lezione 2
 
FROM A TO C(HECK-IN): iOS e Swift Lab
FROM A TO C(HECK-IN): iOS e Swift LabFROM A TO C(HECK-IN): iOS e Swift Lab
FROM A TO C(HECK-IN): iOS e Swift Lab
 
Introduzione a node.js
Introduzione a node.jsIntroduzione a node.js
Introduzione a node.js
 
Introduzione a Node.js
Introduzione a Node.jsIntroduzione a Node.js
Introduzione a Node.js
 
Ionic Cordova vs React Native
Ionic Cordova vs React NativeIonic Cordova vs React Native
Ionic Cordova vs React Native
 
MOBILE APPS con ANDROID - Lo Stretto Digitale
MOBILE APPS con ANDROID  - Lo Stretto DigitaleMOBILE APPS con ANDROID  - Lo Stretto Digitale
MOBILE APPS con ANDROID - Lo Stretto Digitale
 
Webkit meets native development
Webkit meets native developmentWebkit meets native development
Webkit meets native development
 
Introduzione a WatchKit
Introduzione a WatchKitIntroduzione a WatchKit
Introduzione a WatchKit
 
ios 8 - parte 1 - intro - ita
ios 8 - parte 1 - intro - itaios 8 - parte 1 - intro - ita
ios 8 - parte 1 - intro - ita
 
La tua prima app per Ubuntu Touch
La tua prima app per Ubuntu TouchLa tua prima app per Ubuntu Touch
La tua prima app per Ubuntu Touch
 
Modi innovativi per costruire App
Modi innovativi per costruire AppModi innovativi per costruire App
Modi innovativi per costruire App
 

Sviluppo Di Applicazioni Su I Os

  • 1. SVILUPPO APP CON IOS Simone Kalb
  • 2. E tu chi sei? Mi chiamo Simone Kalb Socio del GulCh Junior Software Developer at CRS4 (Open Media Center Lab) System Administrator GNU/Linux e MacOS X avid user
  • 3. 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 venduti da Giugno 2007 [9to5Mac]
  • 4. ...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]
  • 5. Chi è iOS? (a parole) Un sistema : operativo moderno per piattaforme mobili e tablet ideale per gli sviluppatori fortemente orientato all’interazione gestuale
  • 6. 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
  • 7. Perché sviluppare per iOS? Mercato in espansione API semplici e ottimamente documentate Opportunità di business Costi d’ingresso ridicoli
  • 8. 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
  • 9. Ambiente di sviluppo Leopard (10.5)/Snow Leopard (10.6)/Lion (10.7) Beta Xcode v.3.2.5/Xcode v.4.0.2/Xcode 4.2 (Beta) Interface Builder (compreso con Xcode) Eventualmente documentazione reperibile su http://bit.ly/ mqPaHf
  • 10. 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
  • 11. Cosa vediamo quest’oggi? L’ambiente di sviluppo Una semplice applicazione Objective-C Classi IBOutlet e IBAction File’s Owner
  • 12. Cosa vediamo in questo corso? Connessione di oggetti Struttura delle applicazioni I files XIB La delegation La gestione della Memoria Properties
  • 13. Cosa vediamo in questo corso I view Controller Il pattern MVC Esempietto finale
  • 14. Xcode Scarichiamo Xcode da qui (necessaria registrazione gratuita) Doppio click sull’icona .pkg Installiamo anche i tools aggiuntivi Scarichiamo la documentazione per iOS
  • 15. INTERFACCIA DI XCODE Diamo uno sguardo a come si presenta
  • 16. Iniziamo con la prima App File ->New Project (Cmd+Maiusc+N) View-based-Application Nominatelo Hello Build-and-Go Done!
  • 17. 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
  • 18. Risultato Ecco come appare la nostra app
  • 19. 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
  • 20. Modifica al codice HelloViewController.m - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation { // Return YES for supported orientations return YES } Ora premete Build-and-run Complimenti avete creato la vostra prima App per iPhone!
  • 21. 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
  • 22. 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
  • 24. 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
  • 25. Aspetti della sintassi Parentesi quadre nelle chiamate mioCarattere = [miaStringa characterAtIndex :3]; I parametri hanno sempre un nome e due punti (keyword) Le classi hanno un file header e uno d’implementazione Persona.m/Persona.h Altro codice utile può essere importato con import nel file header
  • 26. 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 NSURL che contiene wrapper per file:// e http:// e alt.
  • 27. Organizzazione files in Xcode Classes Other Sources Resources Frameworks Products
  • 28. Modifichiamo la nostra App Chiudiamo il nostro progetto precedente e creiamone un altro Anche questa volta scegliamo View-Based Application Chiamiamolo HelloUser La nostra App saluterà l’utente col il suo nome precedentemente scritto
  • 29. Cosa dobbiamo fare? Dobbiamo creare una label per visualizzare il messaggio Un campo di testo per il nome dell’utente Un pulsante per accettare l’input Un metodo che aggiorni l’etichetta di testo una volta premuto il pulsante
  • 30. Connessioni Per fare ciò che abbiamo descritto è necessario Istruire l’interfaccia grafica con gli elementi Istruire il codice con i metodi appropriati Un riferimento dal codice alla UI si chiama outlet Per definire un oggetto del genere si ricorre ad IBOutlet Per ogni azione, invece, si usa IBAction
  • 31. 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;
  • 32. Particolarità IBAction equivale a void IBAction per il pulsante, non c’è bisogno dell’outlet Pattern (id) sender Oggetto id
  • 33. 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 nella UIText Nel bottone utilizziamo la dicitura “Dimmi Ciao”
  • 34. 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
  • 35. 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 IBAction del File’s Owner In questo caso l’unica scelta disponibile è sayHello:
  • 36. 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]; }
  • 37. 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
  • 38. 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
  • 39. 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
  • 40. 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
  • 41. La delegation La 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”
  • 42. 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
  • 43. 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];
  • 44. ..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
  • 45. 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.
  • 46. 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
  • 47. 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
  • 48. 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
  • 49. Rilasciamo gli oggetti In HelloUserViewController: - (void)dealloc { ! [textField release]; ! [nameField release]; [super dealloc]; } Così siamo sicuri di rilasciare correttamente tutte le variabili in gioco
  • 50. 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
  • 51. 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
  • 52. 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
  • 53. 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
  • 55. MVC 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
  • 56. Apriamo un nuovo progetto File->New Project ->View-Based Application Chiamiamolo Movie Apriamo MovieViewController.xib Aggiungiamo un UIButton alla View Andiamo a modificare il codice
  • 57. 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..
  • 58. 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;
  • 59. ..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
  • 60. 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:
  • 61. Aggiunta di outlet e azioni Nel 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
  • 62. 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
  • 63. 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
  • 64. 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:
  • 65. 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
  • 66. 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
  • 67. 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:
  • 68. 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
  • 69. 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:
  • 70. 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
  • 71. Creazione dell’UI Add->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
  • 72. 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
  • 73. 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
  • 74. MVC.h Il 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
  • 75. 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
  • 76. 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
  • 77. Prima di terminare Alcuni riferimenti Twitter @simonekalb LinkedIn Simone Kalb email: simone@nodelay.org
  • 78. Prima di concludere (ancora..) Un ringraziamento speciale al Java User Group Sardegna ONLUS e a Massimiliano Dessì Un altro ringraziamento particolare a tutti voi che siete intervenuti qui stasera Le slides sono disponibili su SlideShare Per qualsiasi altra cosa chiedete pure..