QUARTA LEZIONE
Menù
UIWebView

Autenticazione su rete

Debug delle App

Apparire sullo store

Pubblicità

Saluti e baci finali
UIWebView
È il controller che si occupa della visualizzazione delle pagine
Web

Supporta HTML 5 e CSS 3

Inoltre è in grado di eseguire codice JavaScript

Supporta le funzioni tap-to-zoom e pinch to zoom nativamente

Ha funzioni per l’autocompleting dei form

Implementa anche un riconoscimento dei paragrafi per lo zoom
Facciamo un piccolo esempio
Vogliamo realizzare un piccolo esempio con UIWebView

Ci potrà decisamente tornare utile in futuro

Apriamo una View-Based Application

Chiamiamola myStupidBrowser

Instanziamo una UITextField e chiamiamola url nel file header
myStupidBrowser

       Istanziamo anche una UIWebView come IBOutlet

       Infine una IBaction e chiamiamola handleGoTapped:

       Dichiariamo la classe col protocollo UITextFieldDelegate
       #import <UIKit/UIKit.h>



@interface myStupidBrowserViewController : UIViewController
!   !      !    !     <UITextFieldDelegate> {
!   IBOutlet UITextField *url;
!   IBOutlet UIWebView *webView;
}

-(IBAction) handleGoTapped;

@end
Le solite modifiche in IB

Fare click su il nostro file xib all’interno del progetto

Aggiungiamo una UITextFiel nella View

Un UIButton con il testo “GO” o “Vai”

Una UIWebView che occupi la parte restante della view

Io ho anche personalizzato il campo testo con il mio sito
Soliti collegamenti
Fare right-click sul file’s Owner

Collegare url al campo di testo

Collegate l’outlet webView alla UIWebView

Collegare infine l’azione handleGoTapped al pulsante “Go”

Ma solo per l’evento Touch Up Inside

Right-click su url e collegate il delegate al File’s Owner e salvate
Scriviamo i metodi

Nel file .m dovremo implementare una funzione chiamata
loadURL:

Questa funzione richiama la funzione loadRequest: di
UIWebView

Questo metodo richiede un NSURLRequest come argomento

Quindi allochiamo una URLRequest con la nostra url
Ora scriviamo il codice

    Scriveremo i seguenti tre metodi:
-(void) loadURL {
!   NSURL *url = [[NSURL alloc] initWithString: urlField.text];
!   NSURLRequest *request = [[NSURLRequest alloc] initWithURL: url];
!   [webView loadRequest: request];
!   [request release];
!   [url release];
}!

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
!   if (textField == urlField) {
!   !      [self handleGoTapped];
!   }
!   return YES;
}

-(IBAction) handleGoTapped {
!   [urlField resignFirstResponder];
!   [self loadURL];
}
Veloci commenti a riguardo


È stato richiamato il metodo resignFirstResponder:

All’interno del metodo handleGoTapped: è richiamato loadURL:

Come già visto textFielShouldRelease: serve per caricare l’URL

Anche se è cliccato il bottone Return
Risultato
Questo è come dovrebbe essere
 visualizzata l’applicazione nel
          simulatore..
Altro

Potreste desiderare di implementare i bottoni avanti ed indietro

Per fare questo basta implementare i metodi goBack: e
goForward:

Per indicare il caricamento della pagina, utilizzate il delegato

Riimplementate i metodi webViewDid{Start, Finish}Loading:

Oppure didFailWithError: che sono i callback necessari
URL LOADING SYSTEM
URL
Non tutto ciò che passa per la 80 è una pagina web

Molte applicazioni si connettono per scaricare informazioni

E reagire di conseguenza

Per questo Apple ha pensato all’URL Loading System

Consente connessioni con quattro protocolli fondamentali

HTTP HTTPS FTP e FILE
Risultato

Il risultato è che possiamo facilmente utilizzare l’esempio
precedente

In cui magari al posto di UIWebView abbiamo un campo di testo

In questo caso loadRequest: non è che l’inizio della sessione

NSURLConnection è l’oggetto di riferimento

Supporta POST, e GET sia per la ricezione che per l’invio
Altri dettagli
Le proprietà POST e GET sono di sola lettura

Per impostarle a valori differenti utilizzare
NSMutableURLRequest

Una corrispondente NSURLResponse è generata in seguito

NSURLConnection rappresenta l’azione di connettersi al server
e di ottenere risposta

L’interazione avviene in modo asincrono (ma anche sincrono)
Vediamo come funziona
         NSURLRequest *request = [[NSURLRequest alloc] initWithURL: url];
!   NSURLConnection *connection = [[NSURLConnection alloc]
!   !      !    !     !    initWithRequest:request
!   !      !    !     !    delegate:self];
!   [connection release];
!   [request release];




    NSURLConnection ha come delegato se stesso

    È per questo che possiamo rilasciare gli oggetti subito

    Al delegato viene notificato qualsiasi evento interessante

    Chiaramente gestiremo l’autenticazione tramite questo oggetto
Alcuni dei callback
connection:didReceiveResponse: sono ricevuti dati sufficienti


connection:didReceiveData: fornisce un wrapper NSData
attorno al più recente blocco di byte

connection:didFinishLoading: il download è stato completato


connection:didFailWithError: restituisce un NSError per
descrivere perché è fallito il download

Per far vedere il caricamento usate il metodo [UIActivity
IndicatorView startAnimating]
Ancora sui callback
Una volta ricevuta la risposta, potete mettere in stop la rotellina

Cercare all’interno della risposta quello che vi interessa

Nel caso in cui abbiamo una risposta di tipo JSON ci
comportiamo come visto nella lezione precedente

Altre idee sono utilizzare una UIProgressView

Impostare il suo valore in base a expectedContentLenght e
aggiornarla periodicamente
Chi ci interessa?


L’evento che c’interessa di più è connection:didReceiveData:

Qualunque cosa decidiate di fare con i dati...

...Fatela qua!

Viene chiamato ogni qualvolta verrà raggiunta la fine del flusso
Andiamo a vedere il codice

    Andiamo a creare un facile esempio, creiamo una NSString e
    aggiungiamo ad un UITextView
    - (void)connection:(NSURLConnection *)connection



!   !      !    !     !    didReceiveData:(NSData *)data {
!   NSLog (@"connectionDidReceiveData");
!   NSString *newText = [[NSString alloc]
!   !      !    !     initWithData:data
!   !      !    !     encoding:NSUTF8StringEncoding];
!   if (newText != NULL) {
!   !      [self appendTextToView:newText];
!   !      [newText release];
!   }
}
Altro

Gli altri due eventi che dovrete gestire sono rispettivamente

  gli eventi di fine

  gli eventi di errore

Per questo motivo vediamo nello specifico cosa possiamo fare

In generale potete sicuramente gestire il comportamento della
UI
Tutto qui?
La cosa più straordinaria è che è tutto qui

Nessun controllo di connessione

Nessun dettaglio di cui occuparsi

Inoltre lavoriamo completamente in asincronia

Col metodo sendSynchronousRequest:returningResponse:error

Si può anche forzare la modalità di blocco
Autenticazione HTTP
Per adesso non possiamo accedere a risorse protette da password

Le richieste di contenuti in un realm protetto rispondono con un
codice HTTP 401 (Non autorizzato)

Fortunatamente abbiamo la possibilità di gestirla con URLLS

Ma per fare questo dobbiamo creare in due passi un realm
protetto

Il Mac in questo ci viene in aiuto
Impostiamo il Realm
Ogni Mac dispone di Apache, che useremo per il test

Apriamo Preferenze->Condivisione->Condivisione Web

Se non è ancora attivo premiamo Start

Annotate l’indirizzo del vs. computer, sarà utile

La Root del webserver è in /Library/WebServer/Documents/

Create una cartella e chiamatela iPhone
Creiamo la pagina
Ora con un editor di testo creiamo una pagina index.html

All’interno della pagina in HTML scriviamo questo codice
<html><head><title>Ok!</title></head>


<body>


<h1>You'reIn!</h1>


<img src="FileSystemExplorer-app-dir.png" />


</body>


</html>
Blocchiamo l’accesso
Ora dovremo bloccare l’accesso alla pagina

Per fare questo modifichiamo i file di configurazione di Apache2

Apriamo un Terminale

Spostiamoci su /etc/apache2/

A questo punto apriamo il file con sudo vi httpd.conf

Andate alla fine del file per inserire i seguenti codici
Modifica di Apache

#Aggiunge un vhost per autenticare la directory iphone

Include /etc/apache/users/*.conf

Passate alla cartella qui di sopra dopo aver salvato il file

Create un nome qualsiasi di file con estensione .conf

All’interno di questo file dichiariamo le informazioni di
autenticazione
iphone.conf
#
# Autenticazione utente/password per directory iphone
#
<Directory "/Library/WebServer/Documents/iphone">
!      AuthType Basic
!      AuthName "Autentica o Muori"
!      AuthUserFile /etc/apache2/iphonoedirpasswd
!      Require user zack
</Directory>




Indichiamo la cartella, indichiamo il tipo di autenticazione

In questo caso forniremo username/password

Indichiamo il file con la password, e i nomi degli utenti
Creiamo il file di password

Una volta fatto questo file dobbiamo generare un file di htpasswd

Creiamo un utente con htpasswd da superuser
sudo htpasswd -c /etc/apache2/iphonedirpasswd zack

Ci verrà chiesta la password e la conferma

Riavviate Apache con sudo apachectrl    restart


Andate a vedere se l’autenticazione è riuscita col browser
Gestire l’autenticazione HTTP

Ora dovremo gestire l’autenticazione tramite URLLS

In questo caso l’autenticazione è gestita dal metodo di callback
del delegato connection:didReceiveAuthenticationChallenge:

Questa restituisce un oggetto NSURLAuthenticationChallenge

Questo rappresenta lo stato del challenge tra domanda e risposta

Potete chiamare quindi diversi metodi per gestire la connessione
Metodi

Il metodo sender restituisce un oggetto

Questo oggetto implementa il protocollo
NSAuthenticationChallengeSender

Questo rappresenta il mittente con cui stabilite una connessione

È con questo che andrete ad interagire quando vi autenticate
Varie opzioni

Potete fare diverse cose una volta individuato il sender

  O rispondere con user/password
  (useCredential:ForAuthenticationChallenge:)

  Oppure continuare senza fornire credenziali
  (continueWithoutCredentialsForAuthenticationChallenge:)

  Oppure rinunciare e annullare la ricerca
  (cancelAuthenticationChallenge:)
Prova pratica
      - (void)connection:(NSURLConnection *)connection
!   didReceiveAuthenticationChallenge:
!   (NSURLAuthenticationChallenge *)challenge {
!   if ([challenge previousFailureCount] != 0) {
// Se la precedente sessione ha count > 0, allora user e password erano errate
!   !      NSString *alertMessage = @"Invalid username or password";
!   !      UIAlertView *authenticationAlert =
!   !      [[UIAlertView alloc] initWithTitle:@"Authentication failed"
!   !      !     !    message:alertMessage
!   !      !     !    delegate:nil
!   !      !     !    cancelButtonTitle:@"OK"
!   !      !     !    otherButtonTitles:nil];
!   !      [authenticationAlert show];
!   !      [authenticationAlert release];
!   !      [alertMessage release];
!   !      [activityIndicator stopAnimating];
!   } else {
!   !      // show and block for authentication challenge
!   !      AuthenticationChallengeViewController *challengeController =
!   !      [[AuthenticationChallengeViewController alloc]
!   !      !     !    initWithNibName:@"AuthenticationChallengeView"
!   !      !     !    bundle:[NSBundle mainBundle]
!   !      !     !    loader: self
!   !      !     !    challenge: challenge];
!   !      [self presentModalViewController:challengeController
!   !      !     !    animated:YES];
!   !      [challengeController release];
!   }
}
Commentiamo il codice

Se il numero di tentativi falliti è >0

Allora abbiamo sbagliato user/pass

Quindi presentiamo un messaggio di errore

Nel caso invece di un nuovo Challenge

Visualizziamo una finestra con la richiesta di tipo modale
Ancora sul codice
L’AuthenticationViewController è una semplice view

È composta da tre UILabels, due per il nome/cognome, una per
il titolo

Due bottoni, uno per Annulla, l’altro per OK

Entrambi i metodi dismettono la view modale e recuperano il
NSURLAuthenticationChallengeSender dal challenge

La differenza è Annulla invia cancelAuthenticationChallenge:
Gestire l’autenticazione

    Notiamo il metodo handleAutentication
    - (void) handleAuthenticationOKForChallenge:



!   !      !    (NSURLAuthenticationChallenge *) aChallenge
!   !      !    withUser: (NSString*) username
!   !      !    password: (NSString*) password {
!   // try to reply to challenge
!   NSURLCredential *credential = [[NSURLCredential alloc]
!   !      !    initWithUser:username
!   !      !    password:password
!   !      !    persistence:NSURLCredentialPersistenceForSession];
!   [[aChallenge sender] useCredential:credential
!   !      !    forAuthenticationChallenge:aChallenge];
!   [credential release];
!   [self dismissModalViewControllerAnimated:YES];
}
Spieghiamo
Viene allocato un oggetto di tipo NSURLCredentials

Questo richiede un argomento persistance:

  NSCredentialsPersistanceNone

  NSCredentialsPersistanceForSession

  NSCredentialsPersistancePermanent

  Solo quest’ultima ha comportamenti diversi su iphone e
  simulatore
Ok for Challenge


      - (void) handleAuthenticationOKForChallenge:
!   !      !     (NSURLAuthenticationChallenge *) aChallenge
!   !      !     withUser: (NSString*) username
!   !      !     password: (NSString*) password {
!   // try to reply to challenge
!   NSURLCredential *credential = [[NSURLCredential alloc]
!   !      !     initWithUser:username
!   !      !     password:password
!   !      !     persistence:NSURLCredentialPersistenceForSession];
!   [[aChallenge sender] useCredential:credential
!   !      !     forAuthenticationChallenge:aChallenge];
!   [credential release];
!   [self dismissModalViewControllerAnimated:YES];
}
Comportamento
Ora abbiamo praticamente finito

Se le credenziali sono state accettate iniziamo a ricevere
chiamate connection:didReceiveData:

Queste contengono il contenuto dell’URL a cui abbiamo
ottenuto l’accesso

Nel nostro caso trattasi di un file HTML

Gli altri metodi sono forniti con l’esempio
APPLICAZIONI PRONTE PER
       LO STORE
E adesso?

La mia applicazione è pronta

Vorrei inserirla nell’App Store

E venderla

Ma non so come fare

E adesso?
Requisiti
Il nostro codice deve essere stabile

Dobbiamo essere all’interno del programma iOS Developers

Ha un prezzo di €79,00 annuali

Può essere fatto da privati o aziende

Consente di testare il software sino a 100 dispositivi

Prima di inviarlo a Apple il codice deve essere testato
Fare delle scelte

Come al solito è necessario fare alcune scelte di carattere
progettuale

Una di queste è fare o meno un’applicazione Universal

Questa girerà sia su iPad che su iPhone

Ha bisogno di ripensare l’interfaccia grafica in ambedue i casi

Anche le azioni saranno differenti
Alcuni accorgimenti
Se volete fare un’applicazione per iPad

Dimenticate di fare un clone di quella per iPhone

Il dispositivo è totalmente differente

Va rivista tutta la UI e la possibilità di inserire dei nuovi elementi

Le app per iPad hanno un differente approccio

Tenete presente che avete un dispositivo che ruota
Cosa sì e cosa no
Saranno respinte:

  App non complete o che crashan

  App che non fanno quello che dicono di fare

  Quelle che usano API non pubbliche

  Quelle che usano funzionalità non documentate

  App in beta, trial o demo
Cosa sì e cosa no
App che sono presenti in massa con le stesse funzionalità (tipo
rutti, scorreggie, Kamasutra)

Devono girare anche in 2X su iPad

Quelle che non offrono funzionalità ma sono specifiche di un sito
Web

Non possono contenere frasi offensive o incitazione alla violenza

Non possono essere limitanti nella fruizione
Poi non venitemi a dire..

Non possono replicare funzionalità del sistema operativo

Non vale spammare l’App Store con App tutte simili

App con Rating inappropriato saranno rimosse

No porno, no violenza o razzismo

Le applicazioni di raccolta fondi devono essere free
Il successo di un’App
Che cosa porta al successo di un’App?

Forse la grafica?

Forse la funzionalità?

Forse la pubblicità?

Forse l’icona?

In realtà un po’ tutte queste cose...
Progettazione
Buttarsi a capofitto su Xcode non è mai una buona idea

Notti di riscrittura del codice vi attendono

Ogni modifica in corso d’opera ha un altissimo costo

Definite una proposizione che descrive l’applicazione

Tracciate un prototipo su carta (sì carta!)

Definite un ADS (Application Definition Statement)
ADS

Un ADS è una frase che serve per spiegare cosa farà l’App

Aiuta a prendere decisioni su caratteristiche ed elementi della UI

L’applicazione diventa molto più centrata e definita

Un buon ADS è composto da 3 parti

  Elemento distintivo, soluzione, tipo di utenza
Elemento distintivo
È ciò che rende speciale la vostra applicazione

Sarà “facile da usare?”

Consente di differenziare la vostra applicazione rispetto alle altre

Può anche essere “graficamente appagante” o “funzionale”

Decidete voi

Più sarete specifici meglio sarà
Soluzione

La soluzione definisce il problema che voi volete risolvere con la
vostra applicazione

Per esempio può servire a condividere le vostre foto

Da questo momento in poi quello sarà l’obiettivo dell’App

Null’altro vi deve distogliere dall’obbiettivo
Tipo di utenza

Definisce l’utente finale della vostra applicazione

L’app delle foto serve per professionisti o per bambini?

Conoscendo l’utenza conoscerete anche il tipo di caratteristiche

Inutile fornire funzioni avanzate se il target è un bambino

Questo si riflette anche sull’interfaccia utente
Tempi

Teoricamente potreste passare anche due settimane nella
definizione delle ADS

Senza neanche scrivere una riga sola di codice

Ma questo non vi deve scoraggiare perché avrete sicuramente in
testa con precisione cosa realizzare

Troppo spesso dipo 100 righe di codice ti rendi conto che la
metafora non era quella corretta
Il dubbio


Quando si perde di vista l’obiettivo quello che succede è:

  O riscrivo da zero l’applicazione

  O rivedo la metafora dell’applicazione

In ciascuno dei due casi abbiamo fallito l’obiettivo
Progettare con matita

Non usate OmniGraffle

Usare la matita

Metter per iscritto le proprie idee non imparare le astuzie per
ottenere un progetto dalla grafica perfetta

Schematizzare in fogli grandi una schermata

Serve anche agli utenti per vedere l’aspetto dell’interfaccia
Disegnare
Quando trovate pezzi di interfaccia che non funzionano

Buttare la carta e creare subito un altro schema

Idee economiche che vengono buttate via se non funzionano

Investire tempo in “cose importanti”

Condividete e rivedete, coinvolgete quante più persone possibile

Avrete un feedback per facilitarvi la creazione dell’interfaccia
Usate la rotazione

Fate anche sempre delle prove sul dispositivo in tutte le
orientazioni

La genta adora utilizzare l’app in qualunque orientazione

Fate quindi un layout coerente in tutte le orientazioni

Ora è arrivato il momento di pensare in maniera creativa

Dovete inserire qualcosa che faccia parlare della vostra App
Fattore WOW!™
Il Fattore WOW!™ è quello che fa parlare le persone

Non appena aperta l’applicazione chi la usa deve rimanere
colpito

Un utilizzo creativo di uno shake del dispositivo

Oppure un’integrazione con i social network

Un evento inaspettato durante l’uso (coerente con la
geolocalizzazione ad esempio)
Pensate sempre all’utente
La caratteristica primaria non deve perdere di vista l’utente

È lui il destinatario, non deve diventare fattore d’ingombro

Non deve distrarci dallo scopo

Lo scossone è davvero utile?

Gli utenti sanno come avviarlo

Esiste una funzione alternativa?
Otteniamo Feedback

Un altro fondamentale step è chiedere un feedback agli utenti

Spesso gli utenti hanno un sacco di idee che a voi non sono
venute in mente

Saprete sicuramente cosa eliminare

Quali aggiustamenti introdurre

Quali funzionalità incorporare
Occhio però...


Non perdere di vista l’obiettivo primario

  La vostra applicazione deve rendere più facile la vita

  Non certo complicarla con inutili fronzoli

  Occhio a non farsi trasportare all’effetto contrario
Perfezionamento
Prima del test agli utenti c’è una parte da non sottovalutare

Facciamo un passo indietro e cerchiamo le parti da perfezionare

Rendere l’applicazione priva d’intoppi e semplice

  Facciamoci delle domande come la seguente:

    Come vengono gestite le telefonate e le interruzioni?

    Le caratteristiche sono facili da trovare e utilizzare?
Perfezionamento

Qual’è il profilo d’uso percepito, l’applicazione si avvia
velocemente?

Alcune aree dell'applicazione utilizzano più energia del dovuto?

Anche se non esiste una risposta, è importante porsele

Gli utenti apprezzano realmente un buon lavoro

Aggiungere uno splash screen è utile in questo frangente
Gestite le interrruzioni

Potete decidere di salvare lo stato dell’applicazione ad ogni
lancio

Potete accedere ad SQLite per salvare lo stato dell’applicazione

Ricordate infine di scegliere l’icona in maniera coerente con
l’applicazione e ben definita

Valutate l’introduzione di notifiche push ma siate accorti nel loro
uso possono diventare molto invadenti
Beta tester
Il beta testing è la parte più importante dell’applicazione

È necessario ascoltare i beta tester e sentire le lamentele

Se tutti danno feedback positivi allora c’è qualcosa che non va

Procuratevi dei profili di distribuzione ad hoc in base all’ID

Una volta finito il tempo del test (anche alcune settimane)

prendere i dati tramite Organizer dell’applicazione
Non esagerate con i fix

Sembra paradossale ma l’applicazione dovrà essere pronta

In realtà l’applicazione disponibile batte sempre quella perfetta

Ora potete affermare di voler arrivare al negozio senza temere

Ci sono ottime probabilità che la vostra applicazione venga
accettata

Risolvete gli aspetti legali della vostra posizione tipo IVA etc.
Altre cose da fare
Riportate firmati i contratti ad Apple

Bisogna essere pazienti e questa prassi dura parecchio

Quando si dice che non si possono utilizzare API private è così

La vostra applicazione viene rifiutata perché Apple non sa cosa
c’è dentro

Per quanto ne sanno loro le vs. librerie potrebbero danneggiare il
dispositivo
Se ottenete un rifiuto
NON suicidarsi

Tutti hanno visto rifiutarsi delle App (anche Google)

Fare un respiro profondo

Chiedersi come mai

Se il motivo vi risulta infondato

Ripresentate il progetto, non prenderlo come un fatto personale
Diffusione
La diffusione è fondamentale, ma è un lavoro a tempo pieno

Diffondete la rete di link al vostro sito, comunicati stampa

Recensioni su iTunes di beta tester

Fondamentale è anche il supporto

Cercate di venire in aiuto degli utenti in difficoltà

Buona fortuna!
Thank you for developing for iOS. Even though this
document is a formidable list of what not to do, please also
keep in mind the much shorter list of what you must do.
Above all else, join us in trying to surprise and delight users.
Show them their world in innovative ways, and let them
interact with it like never before.
In our experience, users really respond to polish, both in
functionality and user interface. Go the extra mile. Give
them more than they expect. And take them places where
they have never been before. We are ready to help.
GRAZIE DELL’ATTENZIONE!

Programming iOS lezione 4

  • 1.
  • 2.
    Menù UIWebView Autenticazione su rete Debugdelle App Apparire sullo store Pubblicità Saluti e baci finali
  • 3.
    UIWebView È il controllerche si occupa della visualizzazione delle pagine Web Supporta HTML 5 e CSS 3 Inoltre è in grado di eseguire codice JavaScript Supporta le funzioni tap-to-zoom e pinch to zoom nativamente Ha funzioni per l’autocompleting dei form Implementa anche un riconoscimento dei paragrafi per lo zoom
  • 4.
    Facciamo un piccoloesempio Vogliamo realizzare un piccolo esempio con UIWebView Ci potrà decisamente tornare utile in futuro Apriamo una View-Based Application Chiamiamola myStupidBrowser Instanziamo una UITextField e chiamiamola url nel file header
  • 5.
    myStupidBrowser Istanziamo anche una UIWebView come IBOutlet Infine una IBaction e chiamiamola handleGoTapped: Dichiariamo la classe col protocollo UITextFieldDelegate #import <UIKit/UIKit.h> @interface myStupidBrowserViewController : UIViewController ! ! ! ! <UITextFieldDelegate> { ! IBOutlet UITextField *url; ! IBOutlet UIWebView *webView; } -(IBAction) handleGoTapped; @end
  • 6.
    Le solite modifichein IB Fare click su il nostro file xib all’interno del progetto Aggiungiamo una UITextFiel nella View Un UIButton con il testo “GO” o “Vai” Una UIWebView che occupi la parte restante della view Io ho anche personalizzato il campo testo con il mio sito
  • 7.
    Soliti collegamenti Fare right-clicksul file’s Owner Collegare url al campo di testo Collegate l’outlet webView alla UIWebView Collegare infine l’azione handleGoTapped al pulsante “Go” Ma solo per l’evento Touch Up Inside Right-click su url e collegate il delegate al File’s Owner e salvate
  • 8.
    Scriviamo i metodi Nelfile .m dovremo implementare una funzione chiamata loadURL: Questa funzione richiama la funzione loadRequest: di UIWebView Questo metodo richiede un NSURLRequest come argomento Quindi allochiamo una URLRequest con la nostra url
  • 9.
    Ora scriviamo ilcodice Scriveremo i seguenti tre metodi: -(void) loadURL { ! NSURL *url = [[NSURL alloc] initWithString: urlField.text]; ! NSURLRequest *request = [[NSURLRequest alloc] initWithURL: url]; ! [webView loadRequest: request]; ! [request release]; ! [url release]; }! - (BOOL)textFieldShouldReturn:(UITextField *)textField { ! if (textField == urlField) { ! ! [self handleGoTapped]; ! } ! return YES; } -(IBAction) handleGoTapped { ! [urlField resignFirstResponder]; ! [self loadURL]; }
  • 10.
    Veloci commenti ariguardo È stato richiamato il metodo resignFirstResponder: All’interno del metodo handleGoTapped: è richiamato loadURL: Come già visto textFielShouldRelease: serve per caricare l’URL Anche se è cliccato il bottone Return
  • 11.
    Risultato Questo è comedovrebbe essere visualizzata l’applicazione nel simulatore..
  • 12.
    Altro Potreste desiderare diimplementare i bottoni avanti ed indietro Per fare questo basta implementare i metodi goBack: e goForward: Per indicare il caricamento della pagina, utilizzate il delegato Riimplementate i metodi webViewDid{Start, Finish}Loading: Oppure didFailWithError: che sono i callback necessari
  • 13.
  • 14.
    URL Non tutto ciòche passa per la 80 è una pagina web Molte applicazioni si connettono per scaricare informazioni E reagire di conseguenza Per questo Apple ha pensato all’URL Loading System Consente connessioni con quattro protocolli fondamentali HTTP HTTPS FTP e FILE
  • 15.
    Risultato Il risultato èche possiamo facilmente utilizzare l’esempio precedente In cui magari al posto di UIWebView abbiamo un campo di testo In questo caso loadRequest: non è che l’inizio della sessione NSURLConnection è l’oggetto di riferimento Supporta POST, e GET sia per la ricezione che per l’invio
  • 16.
    Altri dettagli Le proprietàPOST e GET sono di sola lettura Per impostarle a valori differenti utilizzare NSMutableURLRequest Una corrispondente NSURLResponse è generata in seguito NSURLConnection rappresenta l’azione di connettersi al server e di ottenere risposta L’interazione avviene in modo asincrono (ma anche sincrono)
  • 17.
    Vediamo come funziona NSURLRequest *request = [[NSURLRequest alloc] initWithURL: url]; ! NSURLConnection *connection = [[NSURLConnection alloc] ! ! ! ! ! initWithRequest:request ! ! ! ! ! delegate:self]; ! [connection release]; ! [request release]; NSURLConnection ha come delegato se stesso È per questo che possiamo rilasciare gli oggetti subito Al delegato viene notificato qualsiasi evento interessante Chiaramente gestiremo l’autenticazione tramite questo oggetto
  • 18.
    Alcuni dei callback connection:didReceiveResponse:sono ricevuti dati sufficienti connection:didReceiveData: fornisce un wrapper NSData attorno al più recente blocco di byte connection:didFinishLoading: il download è stato completato connection:didFailWithError: restituisce un NSError per descrivere perché è fallito il download Per far vedere il caricamento usate il metodo [UIActivity IndicatorView startAnimating]
  • 19.
    Ancora sui callback Unavolta ricevuta la risposta, potete mettere in stop la rotellina Cercare all’interno della risposta quello che vi interessa Nel caso in cui abbiamo una risposta di tipo JSON ci comportiamo come visto nella lezione precedente Altre idee sono utilizzare una UIProgressView Impostare il suo valore in base a expectedContentLenght e aggiornarla periodicamente
  • 20.
    Chi ci interessa? L’eventoche c’interessa di più è connection:didReceiveData: Qualunque cosa decidiate di fare con i dati... ...Fatela qua! Viene chiamato ogni qualvolta verrà raggiunta la fine del flusso
  • 21.
    Andiamo a vedereil codice Andiamo a creare un facile esempio, creiamo una NSString e aggiungiamo ad un UITextView - (void)connection:(NSURLConnection *)connection ! ! ! ! ! didReceiveData:(NSData *)data { ! NSLog (@"connectionDidReceiveData"); ! NSString *newText = [[NSString alloc] ! ! ! ! initWithData:data ! ! ! ! encoding:NSUTF8StringEncoding]; ! if (newText != NULL) { ! ! [self appendTextToView:newText]; ! ! [newText release]; ! } }
  • 22.
    Altro Gli altri dueeventi che dovrete gestire sono rispettivamente gli eventi di fine gli eventi di errore Per questo motivo vediamo nello specifico cosa possiamo fare In generale potete sicuramente gestire il comportamento della UI
  • 23.
    Tutto qui? La cosapiù straordinaria è che è tutto qui Nessun controllo di connessione Nessun dettaglio di cui occuparsi Inoltre lavoriamo completamente in asincronia Col metodo sendSynchronousRequest:returningResponse:error Si può anche forzare la modalità di blocco
  • 24.
    Autenticazione HTTP Per adessonon possiamo accedere a risorse protette da password Le richieste di contenuti in un realm protetto rispondono con un codice HTTP 401 (Non autorizzato) Fortunatamente abbiamo la possibilità di gestirla con URLLS Ma per fare questo dobbiamo creare in due passi un realm protetto Il Mac in questo ci viene in aiuto
  • 25.
    Impostiamo il Realm OgniMac dispone di Apache, che useremo per il test Apriamo Preferenze->Condivisione->Condivisione Web Se non è ancora attivo premiamo Start Annotate l’indirizzo del vs. computer, sarà utile La Root del webserver è in /Library/WebServer/Documents/ Create una cartella e chiamatela iPhone
  • 26.
    Creiamo la pagina Oracon un editor di testo creiamo una pagina index.html All’interno della pagina in HTML scriviamo questo codice <html><head><title>Ok!</title></head> <body> <h1>You'reIn!</h1> <img src="FileSystemExplorer-app-dir.png" /> </body> </html>
  • 27.
    Blocchiamo l’accesso Ora dovremobloccare l’accesso alla pagina Per fare questo modifichiamo i file di configurazione di Apache2 Apriamo un Terminale Spostiamoci su /etc/apache2/ A questo punto apriamo il file con sudo vi httpd.conf Andate alla fine del file per inserire i seguenti codici
  • 28.
    Modifica di Apache #Aggiungeun vhost per autenticare la directory iphone Include /etc/apache/users/*.conf Passate alla cartella qui di sopra dopo aver salvato il file Create un nome qualsiasi di file con estensione .conf All’interno di questo file dichiariamo le informazioni di autenticazione
  • 29.
    iphone.conf # # Autenticazione utente/passwordper directory iphone # <Directory "/Library/WebServer/Documents/iphone"> ! AuthType Basic ! AuthName "Autentica o Muori" ! AuthUserFile /etc/apache2/iphonoedirpasswd ! Require user zack </Directory> Indichiamo la cartella, indichiamo il tipo di autenticazione In questo caso forniremo username/password Indichiamo il file con la password, e i nomi degli utenti
  • 30.
    Creiamo il filedi password Una volta fatto questo file dobbiamo generare un file di htpasswd Creiamo un utente con htpasswd da superuser sudo htpasswd -c /etc/apache2/iphonedirpasswd zack Ci verrà chiesta la password e la conferma Riavviate Apache con sudo apachectrl restart Andate a vedere se l’autenticazione è riuscita col browser
  • 31.
    Gestire l’autenticazione HTTP Oradovremo gestire l’autenticazione tramite URLLS In questo caso l’autenticazione è gestita dal metodo di callback del delegato connection:didReceiveAuthenticationChallenge: Questa restituisce un oggetto NSURLAuthenticationChallenge Questo rappresenta lo stato del challenge tra domanda e risposta Potete chiamare quindi diversi metodi per gestire la connessione
  • 32.
    Metodi Il metodo senderrestituisce un oggetto Questo oggetto implementa il protocollo NSAuthenticationChallengeSender Questo rappresenta il mittente con cui stabilite una connessione È con questo che andrete ad interagire quando vi autenticate
  • 33.
    Varie opzioni Potete farediverse cose una volta individuato il sender O rispondere con user/password (useCredential:ForAuthenticationChallenge:) Oppure continuare senza fornire credenziali (continueWithoutCredentialsForAuthenticationChallenge:) Oppure rinunciare e annullare la ricerca (cancelAuthenticationChallenge:)
  • 34.
    Prova pratica - (void)connection:(NSURLConnection *)connection ! didReceiveAuthenticationChallenge: ! (NSURLAuthenticationChallenge *)challenge { ! if ([challenge previousFailureCount] != 0) { // Se la precedente sessione ha count > 0, allora user e password erano errate ! ! NSString *alertMessage = @"Invalid username or password"; ! ! UIAlertView *authenticationAlert = ! ! [[UIAlertView alloc] initWithTitle:@"Authentication failed" ! ! ! ! message:alertMessage ! ! ! ! delegate:nil ! ! ! ! cancelButtonTitle:@"OK" ! ! ! ! otherButtonTitles:nil]; ! ! [authenticationAlert show]; ! ! [authenticationAlert release]; ! ! [alertMessage release]; ! ! [activityIndicator stopAnimating]; ! } else { ! ! // show and block for authentication challenge ! ! AuthenticationChallengeViewController *challengeController = ! ! [[AuthenticationChallengeViewController alloc] ! ! ! ! initWithNibName:@"AuthenticationChallengeView" ! ! ! ! bundle:[NSBundle mainBundle] ! ! ! ! loader: self ! ! ! ! challenge: challenge]; ! ! [self presentModalViewController:challengeController ! ! ! ! animated:YES]; ! ! [challengeController release]; ! } }
  • 35.
    Commentiamo il codice Seil numero di tentativi falliti è >0 Allora abbiamo sbagliato user/pass Quindi presentiamo un messaggio di errore Nel caso invece di un nuovo Challenge Visualizziamo una finestra con la richiesta di tipo modale
  • 36.
    Ancora sul codice L’AuthenticationViewControllerè una semplice view È composta da tre UILabels, due per il nome/cognome, una per il titolo Due bottoni, uno per Annulla, l’altro per OK Entrambi i metodi dismettono la view modale e recuperano il NSURLAuthenticationChallengeSender dal challenge La differenza è Annulla invia cancelAuthenticationChallenge:
  • 37.
    Gestire l’autenticazione Notiamo il metodo handleAutentication - (void) handleAuthenticationOKForChallenge: ! ! ! (NSURLAuthenticationChallenge *) aChallenge ! ! ! withUser: (NSString*) username ! ! ! password: (NSString*) password { ! // try to reply to challenge ! NSURLCredential *credential = [[NSURLCredential alloc] ! ! ! initWithUser:username ! ! ! password:password ! ! ! persistence:NSURLCredentialPersistenceForSession]; ! [[aChallenge sender] useCredential:credential ! ! ! forAuthenticationChallenge:aChallenge]; ! [credential release]; ! [self dismissModalViewControllerAnimated:YES]; }
  • 38.
    Spieghiamo Viene allocato unoggetto di tipo NSURLCredentials Questo richiede un argomento persistance: NSCredentialsPersistanceNone NSCredentialsPersistanceForSession NSCredentialsPersistancePermanent Solo quest’ultima ha comportamenti diversi su iphone e simulatore
  • 39.
    Ok for Challenge - (void) handleAuthenticationOKForChallenge: ! ! ! (NSURLAuthenticationChallenge *) aChallenge ! ! ! withUser: (NSString*) username ! ! ! password: (NSString*) password { ! // try to reply to challenge ! NSURLCredential *credential = [[NSURLCredential alloc] ! ! ! initWithUser:username ! ! ! password:password ! ! ! persistence:NSURLCredentialPersistenceForSession]; ! [[aChallenge sender] useCredential:credential ! ! ! forAuthenticationChallenge:aChallenge]; ! [credential release]; ! [self dismissModalViewControllerAnimated:YES]; }
  • 40.
    Comportamento Ora abbiamo praticamentefinito Se le credenziali sono state accettate iniziamo a ricevere chiamate connection:didReceiveData: Queste contengono il contenuto dell’URL a cui abbiamo ottenuto l’accesso Nel nostro caso trattasi di un file HTML Gli altri metodi sono forniti con l’esempio
  • 41.
  • 42.
    E adesso? La miaapplicazione è pronta Vorrei inserirla nell’App Store E venderla Ma non so come fare E adesso?
  • 43.
    Requisiti Il nostro codicedeve essere stabile Dobbiamo essere all’interno del programma iOS Developers Ha un prezzo di €79,00 annuali Può essere fatto da privati o aziende Consente di testare il software sino a 100 dispositivi Prima di inviarlo a Apple il codice deve essere testato
  • 44.
    Fare delle scelte Comeal solito è necessario fare alcune scelte di carattere progettuale Una di queste è fare o meno un’applicazione Universal Questa girerà sia su iPad che su iPhone Ha bisogno di ripensare l’interfaccia grafica in ambedue i casi Anche le azioni saranno differenti
  • 45.
    Alcuni accorgimenti Se voletefare un’applicazione per iPad Dimenticate di fare un clone di quella per iPhone Il dispositivo è totalmente differente Va rivista tutta la UI e la possibilità di inserire dei nuovi elementi Le app per iPad hanno un differente approccio Tenete presente che avete un dispositivo che ruota
  • 46.
    Cosa sì ecosa no Saranno respinte: App non complete o che crashan App che non fanno quello che dicono di fare Quelle che usano API non pubbliche Quelle che usano funzionalità non documentate App in beta, trial o demo
  • 47.
    Cosa sì ecosa no App che sono presenti in massa con le stesse funzionalità (tipo rutti, scorreggie, Kamasutra) Devono girare anche in 2X su iPad Quelle che non offrono funzionalità ma sono specifiche di un sito Web Non possono contenere frasi offensive o incitazione alla violenza Non possono essere limitanti nella fruizione
  • 48.
    Poi non venitemia dire.. Non possono replicare funzionalità del sistema operativo Non vale spammare l’App Store con App tutte simili App con Rating inappropriato saranno rimosse No porno, no violenza o razzismo Le applicazioni di raccolta fondi devono essere free
  • 49.
    Il successo diun’App Che cosa porta al successo di un’App? Forse la grafica? Forse la funzionalità? Forse la pubblicità? Forse l’icona? In realtà un po’ tutte queste cose...
  • 50.
    Progettazione Buttarsi a capofittosu Xcode non è mai una buona idea Notti di riscrittura del codice vi attendono Ogni modifica in corso d’opera ha un altissimo costo Definite una proposizione che descrive l’applicazione Tracciate un prototipo su carta (sì carta!) Definite un ADS (Application Definition Statement)
  • 51.
    ADS Un ADS èuna frase che serve per spiegare cosa farà l’App Aiuta a prendere decisioni su caratteristiche ed elementi della UI L’applicazione diventa molto più centrata e definita Un buon ADS è composto da 3 parti Elemento distintivo, soluzione, tipo di utenza
  • 52.
    Elemento distintivo È ciòche rende speciale la vostra applicazione Sarà “facile da usare?” Consente di differenziare la vostra applicazione rispetto alle altre Può anche essere “graficamente appagante” o “funzionale” Decidete voi Più sarete specifici meglio sarà
  • 53.
    Soluzione La soluzione definisceil problema che voi volete risolvere con la vostra applicazione Per esempio può servire a condividere le vostre foto Da questo momento in poi quello sarà l’obiettivo dell’App Null’altro vi deve distogliere dall’obbiettivo
  • 54.
    Tipo di utenza Definiscel’utente finale della vostra applicazione L’app delle foto serve per professionisti o per bambini? Conoscendo l’utenza conoscerete anche il tipo di caratteristiche Inutile fornire funzioni avanzate se il target è un bambino Questo si riflette anche sull’interfaccia utente
  • 55.
    Tempi Teoricamente potreste passareanche due settimane nella definizione delle ADS Senza neanche scrivere una riga sola di codice Ma questo non vi deve scoraggiare perché avrete sicuramente in testa con precisione cosa realizzare Troppo spesso dipo 100 righe di codice ti rendi conto che la metafora non era quella corretta
  • 56.
    Il dubbio Quando siperde di vista l’obiettivo quello che succede è: O riscrivo da zero l’applicazione O rivedo la metafora dell’applicazione In ciascuno dei due casi abbiamo fallito l’obiettivo
  • 57.
    Progettare con matita Nonusate OmniGraffle Usare la matita Metter per iscritto le proprie idee non imparare le astuzie per ottenere un progetto dalla grafica perfetta Schematizzare in fogli grandi una schermata Serve anche agli utenti per vedere l’aspetto dell’interfaccia
  • 58.
    Disegnare Quando trovate pezzidi interfaccia che non funzionano Buttare la carta e creare subito un altro schema Idee economiche che vengono buttate via se non funzionano Investire tempo in “cose importanti” Condividete e rivedete, coinvolgete quante più persone possibile Avrete un feedback per facilitarvi la creazione dell’interfaccia
  • 59.
    Usate la rotazione Fateanche sempre delle prove sul dispositivo in tutte le orientazioni La genta adora utilizzare l’app in qualunque orientazione Fate quindi un layout coerente in tutte le orientazioni Ora è arrivato il momento di pensare in maniera creativa Dovete inserire qualcosa che faccia parlare della vostra App
  • 60.
    Fattore WOW!™ Il FattoreWOW!™ è quello che fa parlare le persone Non appena aperta l’applicazione chi la usa deve rimanere colpito Un utilizzo creativo di uno shake del dispositivo Oppure un’integrazione con i social network Un evento inaspettato durante l’uso (coerente con la geolocalizzazione ad esempio)
  • 61.
    Pensate sempre all’utente Lacaratteristica primaria non deve perdere di vista l’utente È lui il destinatario, non deve diventare fattore d’ingombro Non deve distrarci dallo scopo Lo scossone è davvero utile? Gli utenti sanno come avviarlo Esiste una funzione alternativa?
  • 62.
    Otteniamo Feedback Un altrofondamentale step è chiedere un feedback agli utenti Spesso gli utenti hanno un sacco di idee che a voi non sono venute in mente Saprete sicuramente cosa eliminare Quali aggiustamenti introdurre Quali funzionalità incorporare
  • 63.
    Occhio però... Non perderedi vista l’obiettivo primario La vostra applicazione deve rendere più facile la vita Non certo complicarla con inutili fronzoli Occhio a non farsi trasportare all’effetto contrario
  • 64.
    Perfezionamento Prima del testagli utenti c’è una parte da non sottovalutare Facciamo un passo indietro e cerchiamo le parti da perfezionare Rendere l’applicazione priva d’intoppi e semplice Facciamoci delle domande come la seguente: Come vengono gestite le telefonate e le interruzioni? Le caratteristiche sono facili da trovare e utilizzare?
  • 65.
    Perfezionamento Qual’è il profilod’uso percepito, l’applicazione si avvia velocemente? Alcune aree dell'applicazione utilizzano più energia del dovuto? Anche se non esiste una risposta, è importante porsele Gli utenti apprezzano realmente un buon lavoro Aggiungere uno splash screen è utile in questo frangente
  • 66.
    Gestite le interrruzioni Potetedecidere di salvare lo stato dell’applicazione ad ogni lancio Potete accedere ad SQLite per salvare lo stato dell’applicazione Ricordate infine di scegliere l’icona in maniera coerente con l’applicazione e ben definita Valutate l’introduzione di notifiche push ma siate accorti nel loro uso possono diventare molto invadenti
  • 67.
    Beta tester Il betatesting è la parte più importante dell’applicazione È necessario ascoltare i beta tester e sentire le lamentele Se tutti danno feedback positivi allora c’è qualcosa che non va Procuratevi dei profili di distribuzione ad hoc in base all’ID Una volta finito il tempo del test (anche alcune settimane) prendere i dati tramite Organizer dell’applicazione
  • 68.
    Non esagerate coni fix Sembra paradossale ma l’applicazione dovrà essere pronta In realtà l’applicazione disponibile batte sempre quella perfetta Ora potete affermare di voler arrivare al negozio senza temere Ci sono ottime probabilità che la vostra applicazione venga accettata Risolvete gli aspetti legali della vostra posizione tipo IVA etc.
  • 69.
    Altre cose dafare Riportate firmati i contratti ad Apple Bisogna essere pazienti e questa prassi dura parecchio Quando si dice che non si possono utilizzare API private è così La vostra applicazione viene rifiutata perché Apple non sa cosa c’è dentro Per quanto ne sanno loro le vs. librerie potrebbero danneggiare il dispositivo
  • 70.
    Se ottenete unrifiuto NON suicidarsi Tutti hanno visto rifiutarsi delle App (anche Google) Fare un respiro profondo Chiedersi come mai Se il motivo vi risulta infondato Ripresentate il progetto, non prenderlo come un fatto personale
  • 71.
    Diffusione La diffusione èfondamentale, ma è un lavoro a tempo pieno Diffondete la rete di link al vostro sito, comunicati stampa Recensioni su iTunes di beta tester Fondamentale è anche il supporto Cercate di venire in aiuto degli utenti in difficoltà Buona fortuna!
  • 72.
    Thank you fordeveloping for iOS. Even though this document is a formidable list of what not to do, please also keep in mind the much shorter list of what you must do. Above all else, join us in trying to surprise and delight users. Show them their world in innovative ways, and let them interact with it like never before. In our experience, users really respond to polish, both in functionality and user interface. Go the extra mile. Give them more than they expect. And take them places where they have never been before. We are ready to help.
  • 73.