Programming iOS lezione 4
-
Upload
nodelay-software -
Category
Technology
-
view
1.912 -
download
1
Transcript of Programming iOS lezione 4
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
RisultatoQuesto è 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 callbackconnection: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 paginaOra 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];}
SpieghiamoViene 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!