際際滷

際際滷Share a Scribd company logo
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 lautocompleting 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 allinterno 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 files Owner

Collegare url al campo di testo

Collegate loutlet webView alla UIWebView

Collegare infine lazione handleGoTapped al pulsante Go

Ma solo per levento Touch Up Inside

Right-click su url e collegate il delegate al Files 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:

Allinterno del metodo handleGoTapped: 竪 richiamato loadURL:

Come gi visto textFielShouldRelease: serve per caricare lURL

Anche se 竪 cliccato il bottone Return
Risultato
Questo 竪 come dovrebbe essere
 visualizzata lapplicazione 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 allURL Loading System

Consente connessioni con quattro protocolli fondamentali

HTTP HTTPS FTP e FILE
Risultato

Il risultato 竪 che possiamo facilmente utilizzare lesempio
precedente

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

In questo caso loadRequest: non 竪 che linizio della sessione

NSURLConnection 竪 loggetto di riferimento

Supporta POST, e GET sia per la ricezione che per linvio
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 lazione di connettersi al server
e di ottenere risposta

Linterazione 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 lautenticazione 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 allinterno 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?


Levento che cinteressa 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 lindirizzo 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

Allinterno della pagina in HTML scriviamo questo codice
<html><head><title>Ok!</title></head>


<body>


<h1>You'reIn!</h1>


<img src=/slideshow/programming-ios-lezione-4/7521397/"FileSystemExplorer-app-dir.png" />


</body>


</html>
Blocchiamo laccesso
Ora dovremo bloccare laccesso 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

Allinterno 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 lautenticazione 竪 riuscita col browser
Gestire lautenticazione HTTP

Ora dovremo gestire lautenticazione tramite URLLS

In questo caso lautenticazione 竪 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
LAuthenticationViewController 竪 una semplice view

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

Due bottoni, uno per Annulla, laltro per OK

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

La differenza 竪 Annulla invia cancelAuthenticationChallenge:
Gestire lautenticazione

    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 questultima 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 dellURL a cui abbiamo
ottenuto laccesso

Nel nostro caso trattasi di un file HTML

Gli altri metodi sono forniti con lesempio
APPLICAZIONI PRONTE PER
       LO STORE
E adesso?

La mia applicazione 竪 pronta

Vorrei inserirla nellApp Store

E venderla

Ma non so come fare

E adesso?
Requisiti
Il nostro codice deve essere stabile

Dobbiamo essere allinterno 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 unapplicazione Universal

Questa girer sia su iPad che su iPhone

Ha bisogno di ripensare linterfaccia grafica in ambedue i casi

Anche le azioni saranno differenti
Alcuni accorgimenti
Se volete fare unapplicazione 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 lApp 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 unApp
Che cosa porta al successo di unApp?

Forse la grafica?

Forse la funzionalit?

Forse la pubblicit?

Forse licona?

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 dopera ha un altissimo costo

Definite una proposizione che descrive lapplicazione

Tracciate un prototipo su carta (s狸 carta!)

Definite un ADS (Application Definition Statement)
ADS

Un ADS 竪 una frase che serve per spiegare cosa far lApp

Aiuta a prendere decisioni su caratteristiche ed elementi della UI

Lapplicazione 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 lobiettivo dellApp

Nullaltro vi deve distogliere dallobbiettivo
Tipo di utenza

Definisce lutente finale della vostra applicazione

Lapp delle foto serve per professionisti o per bambini?

Conoscendo lutenza conoscerete anche il tipo di caratteristiche

Inutile fornire funzioni avanzate se il target 竪 un bambino

Questo si riflette anche sullinterfaccia 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 lobiettivo quello che succede 竪:

  O riscrivo da zero lapplicazione

  O rivedo la metafora dellapplicazione

In ciascuno dei due casi abbiamo fallito lobiettivo
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 laspetto dellinterfaccia
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 dellinterfaccia
Usate la rotazione

Fate anche sempre delle prove sul dispositivo in tutte le
orientazioni

La genta adora utilizzare lapp 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 lapplicazione chi la usa deve rimanere
colpito

Un utilizzo creativo di uno shake del dispositivo

Oppure unintegrazione con i social network

Un evento inaspettato durante luso (coerente con la
geolocalizzazione ad esempio)
Pensate sempre allutente
La caratteristica primaria non deve perdere di vista lutente

 lui il destinatario, non deve diventare fattore dingombro

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 lobiettivo primario

  La vostra applicazione deve rendere pi湛 facile la vita

  Non certo complicarla con inutili fronzoli

  Occhio a non farsi trasportare alleffetto contrario
Perfezionamento
Prima del test agli utenti c竪 una parte da non sottovalutare

Facciamo un passo indietro e cerchiamo le parti da perfezionare

Rendere lapplicazione priva dintoppi 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 duso percepito, lapplicazione 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 dellapplicazione ad ogni
lancio

Potete accedere ad SQLite per salvare lo stato dellapplicazione

Ricordate infine di scegliere licona in maniera coerente con
lapplicazione e ben definita

Valutate lintroduzione di notifiche push ma siate accorti nel loro
uso possono diventare molto invadenti
Beta tester
Il beta testing 竪 la parte pi湛 importante dellapplicazione

 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 allID

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

prendere i dati tramite Organizer dellapplicazione
Non esagerate con i fix

Sembra paradossale ma lapplicazione dovr essere pronta

In realt lapplicazione 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 DELLATTENZIONE!

More Related Content

Programming iOS lezione 4

  • 2. Men湛 UIWebView Autenticazione su rete Debug delle App Apparire sullo store Pubblicit Saluti e baci finali
  • 3. 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 lautocompleting dei form Implementa anche un riconoscimento dei paragrafi per lo zoom
  • 4. 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
  • 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 modifiche in IB Fare click su il nostro file xib allinterno 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-click sul files Owner Collegare url al campo di testo Collegate loutlet webView alla UIWebView Collegare infine lazione handleGoTapped al pulsante Go Ma solo per levento Touch Up Inside Right-click su url e collegate il delegate al Files Owner e salvate
  • 8. 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
  • 9. 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]; }
  • 10. Veloci commenti a riguardo stato richiamato il metodo resignFirstResponder: Allinterno del metodo handleGoTapped: 竪 richiamato loadURL: Come gi visto textFielShouldRelease: serve per caricare lURL Anche se 竪 cliccato il bottone Return
  • 11. Risultato Questo 竪 come dovrebbe essere visualizzata lapplicazione nel simulatore..
  • 12. 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
  • 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 allURL Loading System Consente connessioni con quattro protocolli fondamentali HTTP HTTPS FTP e FILE
  • 15. Risultato Il risultato 竪 che possiamo facilmente utilizzare lesempio precedente In cui magari al posto di UIWebView abbiamo un campo di testo In questo caso loadRequest: non 竪 che linizio della sessione NSURLConnection 竪 loggetto di riferimento Supporta POST, e GET sia per la ricezione che per linvio
  • 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 lazione di connettersi al server e di ottenere risposta Linterazione 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 lautenticazione 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 Una volta ricevuta la risposta, potete mettere in stop la rotellina Cercare allinterno 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? Levento che cinteressa 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 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]; ! } }
  • 22. 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
  • 23. 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
  • 24. 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
  • 25. 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 lindirizzo del vs. computer, sar utile La Root del webserver 竪 in /Library/WebServer/Documents/ Create una cartella e chiamatela iPhone
  • 26. Creiamo la pagina Ora con un editor di testo creiamo una pagina index.html Allinterno della pagina in HTML scriviamo questo codice <html><head><title>Ok!</title></head> <body> <h1>You'reIn!</h1> <img src=/slideshow/programming-ios-lezione-4/7521397/"FileSystemExplorer-app-dir.png" /> </body> </html>
  • 27. Blocchiamo laccesso Ora dovremo bloccare laccesso 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 #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 Allinterno di questo file dichiariamo le informazioni di autenticazione
  • 29. 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
  • 30. 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 lautenticazione 竪 riuscita col browser
  • 31. Gestire lautenticazione HTTP Ora dovremo gestire lautenticazione tramite URLLS In questo caso lautenticazione 竪 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 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
  • 33. 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:)
  • 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 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
  • 36. Ancora sul codice LAuthenticationViewController 竪 una semplice view composta da tre UILabels, due per il nome/cognome, una per il titolo Due bottoni, uno per Annulla, laltro per OK Entrambi i metodi dismettono la view modale e recuperano il NSURLAuthenticationChallengeSender dal challenge La differenza 竪 Annulla invia cancelAuthenticationChallenge:
  • 37. Gestire lautenticazione 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 un oggetto di tipo NSURLCredentials Questo richiede un argomento persistance: NSCredentialsPersistanceNone NSCredentialsPersistanceForSession NSCredentialsPersistancePermanent Solo questultima 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 praticamente finito Se le credenziali sono state accettate iniziamo a ricevere chiamate connection:didReceiveData: Queste contengono il contenuto dellURL a cui abbiamo ottenuto laccesso Nel nostro caso trattasi di un file HTML Gli altri metodi sono forniti con lesempio
  • 42. E adesso? La mia applicazione 竪 pronta Vorrei inserirla nellApp Store E venderla Ma non so come fare E adesso?
  • 43. Requisiti Il nostro codice deve essere stabile Dobbiamo essere allinterno 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 Come al solito 竪 necessario fare alcune scelte di carattere progettuale Una di queste 竪 fare o meno unapplicazione Universal Questa girer sia su iPad che su iPhone Ha bisogno di ripensare linterfaccia grafica in ambedue i casi Anche le azioni saranno differenti
  • 45. Alcuni accorgimenti Se volete fare unapplicazione 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狸 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
  • 47. 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
  • 48. Poi non venitemi a dire.. Non possono replicare funzionalit del sistema operativo Non vale spammare lApp 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 di unApp Che cosa porta al successo di unApp? Forse la grafica? Forse la funzionalit? Forse la pubblicit? Forse licona? In realt un po tutte queste cose...
  • 50. Progettazione Buttarsi a capofitto su Xcode non 竪 mai una buona idea Notti di riscrittura del codice vi attendono Ogni modifica in corso dopera ha un altissimo costo Definite una proposizione che descrive lapplicazione 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 lApp Aiuta a prendere decisioni su caratteristiche ed elementi della UI Lapplicazione 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 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 lobiettivo dellApp Nullaltro vi deve distogliere dallobbiettivo
  • 54. Tipo di utenza Definisce lutente finale della vostra applicazione Lapp delle foto serve per professionisti o per bambini? Conoscendo lutenza conoscerete anche il tipo di caratteristiche Inutile fornire funzioni avanzate se il target 竪 un bambino Questo si riflette anche sullinterfaccia utente
  • 55. 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
  • 56. Il dubbio Quando si perde di vista lobiettivo quello che succede 竪: O riscrivo da zero lapplicazione O rivedo la metafora dellapplicazione In ciascuno dei due casi abbiamo fallito lobiettivo
  • 57. 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 laspetto dellinterfaccia
  • 58. 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 dellinterfaccia
  • 59. Usate la rotazione Fate anche sempre delle prove sul dispositivo in tutte le orientazioni La genta adora utilizzare lapp 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 Fattore WOW! 竪 quello che fa parlare le persone Non appena aperta lapplicazione chi la usa deve rimanere colpito Un utilizzo creativo di uno shake del dispositivo Oppure unintegrazione con i social network Un evento inaspettato durante luso (coerente con la geolocalizzazione ad esempio)
  • 61. Pensate sempre allutente La caratteristica primaria non deve perdere di vista lutente lui il destinatario, non deve diventare fattore dingombro Non deve distrarci dallo scopo Lo scossone 竪 davvero utile? Gli utenti sanno come avviarlo Esiste una funzione alternativa?
  • 62. 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
  • 63. Occhio per嘆... Non perdere di vista lobiettivo primario La vostra applicazione deve rendere pi湛 facile la vita Non certo complicarla con inutili fronzoli Occhio a non farsi trasportare alleffetto contrario
  • 64. Perfezionamento Prima del test agli utenti c竪 una parte da non sottovalutare Facciamo un passo indietro e cerchiamo le parti da perfezionare Rendere lapplicazione priva dintoppi 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 profilo duso percepito, lapplicazione 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 Potete decidere di salvare lo stato dellapplicazione ad ogni lancio Potete accedere ad SQLite per salvare lo stato dellapplicazione Ricordate infine di scegliere licona in maniera coerente con lapplicazione e ben definita Valutate lintroduzione di notifiche push ma siate accorti nel loro uso possono diventare molto invadenti
  • 67. Beta tester Il beta testing 竪 la parte pi湛 importante dellapplicazione 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 allID Una volta finito il tempo del test (anche alcune settimane) prendere i dati tramite Organizer dellapplicazione
  • 68. Non esagerate con i fix Sembra paradossale ma lapplicazione dovr essere pronta In realt lapplicazione 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 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
  • 70. 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
  • 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 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.