Post on 20-Jun-2015
TERZA LEZIONE
JSON
JSON (JavaScript Object Notation) è un protocollo molto leggero per scambio d’informazioni
È basato su un sottoinsieme di JavaScript
È un formato di testo completamente indipendente dalla piattaforma
Usa delle convenzioni familiari per i programmatori C/C++/JS
Queste proprietà rendono JSON perfetto per lo scambio di dati
JSON
JSON si basa su due strutture:
Una collezione di coppie chiave valore (tipicamente Objects)
Una lista ordinata di valori (tipicamente Arrays)
La sintassi è talmente semplice che qualunque linguaggio lo gestisce facilmente
Objects
Un oggetto è una lista non ordinata di coppie chiave/valore
Un oggetto inizia con { e termina con }
Ogni nome è seguito da due punti :
Le coppie sono separate da una virgola ,
Ad esempio {nome:valore, nome2: valore2}
Arrays
Un Array, invece, è una lista di valori ordinati
Un array inizia con una parentesi quadra [
Un array finisce con una parentesi quadra ]
Ogni valore è separato da una virgola
Es. [valore, valore1, valore2, ....]
Values
Un valore può essere un oggetto di diversi tipi
Può avere valori annidati
String
Number
Object (anche null)
{true, false}
Strings
Le strings possono essere di vario genere
Sono sempre racchiuse da apici “”
Possono essere usati i soliti escaped characters
Ad esempio \n, \t, \f, \\, \/
Oppure caratteri unicode in esadecimale con \u007E (~)
Numbers
Anche i numeri hanno una rappresentazione standard
Possono essere negativi con un - davanti
Contengono . per i decimali
Infine possono avere la notazione scientifica {e,E}±
Esempi 1.2E23, 13.2e-12
JSON per Objective-C
JSON è veramente platform-independent
Esistono librerie per QUALUNQUE linguaggio
È parte dell’RFC 4627
È come XML ma senza la parte “grassa”
Noi vedremo la sua implementazione in Objective-C
Chiamata JSON-Framework
JSON FrameworkJSON parser e generator
Aggiunge nuove categorie agli oggetti Objective-C
Fornisce API per il controllo degli oggetti
Fornisce uno stack di errori per capire in caso di codice non valido
Ricorsione configurabile per maggiore sicurezza
L’ouput può essere direttamente incluso in dizionari
Come installarlo
JSON Framework è un progetto Open Source di Stig Brautaset
È possibile scaricare il codice da GitHub
Per scaricare l’ultima versione è necessario usare il tool git
Su Mac il tool è semplice da scaricare da qui
Chi vuole si può installare anche il tool GitX che fornisce una pratica GUI per analizzare i progetti GIT
Clonare il repo
Per scaricare da Git un progetto è necessario il tool git
Aprire un terminale e digitare:
cd ~/cartellaMioProgetto/
git clone git://github.com/stig/json-framework
È necessario copiare i files nel progetto
Come al solito Add->Existing File.. e selezionare Classes
Predisporre l’ambiente
Inseriti i files della libreria nel nostro progetto,
Creiamo una classe Obj-C con Add->New File..
Ereditiamo da NSObject
Chiamiamo la classe JSONSupport
E definiamo i vari metodi di accesso alla classe
OppurePossiamo direttamente richiamare la libreria dal progetto
Nel nostro RootViewController importiamo JSON.h
#import <JSON/JSON.h>
Dichiariamo una variabile d’appoggio jsonArray nel file .h
@interface RootViewController : UITableViewController {
! NSMutableArray *jsonArray; }
@property (nonatomic, retain) NSMutableArray *jsonArray;
Altre aggiunte
Ora sintetizziamo la variabile che ci serve
@synthesize jsonArray;
Ora non ci resta che includere il codice in viewDidLoad:- (void)viewDidLoad {! NSURL *jsonURL = [NSURL URLWithString:@"http://tsc.prossimaisola.com/mobile/it/contenuto/all/1,4/json"];! NSString *jsonData = [[NSString alloc] initWithContentsOfURL:jsonURL];! NSLog(jsonData);! // Converte il dato json in un’array! self.jsonArray = [jsonData JSONValue]; ! //NSLog(@"count is: %i", [self.jsonArray count]);!}
Possiamo decidere la stringa in maniera totalmente arbitraria
Altre piccole modifiche
Adesso è necessario istruire il nostro RVC riguardo l’array- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
! return [jsonArray count];}
Infine nella funzione cellForRowAtIndexPath: configurare la cella che ci servirà
cell.text = (NSString *)[self.jsonArray objectAtIndex:indexPath.row];
Liberiamo le variabili
È ora giunto il momento di liberare la memoria dal nostro codice- (void)dealloc {! [jsonArray dealloc];! [super dealloc];}
Una volta che abbiamo l’oggetto jsonArray saremo in grado di parsare il codice
In pratica abbiamo fatto qualche precisazione nel codice del progetto
Più avanti vediamo come abbiamo fatto
Leggere e scrivere su/da files
iOS permette di creare files e di scriverne il contenuto
Teoricamente alcuni tipi di oggetto supportano writeToFile:
È necessario specificare semplicemente un fileName
Per fare questo basta una variabile di tipo NSString
Bisogna però specificare anche la directory in cui scrivere
Andiamo quindi a vedere tutto il metodo
ScrivereScrivere su file è molto semplice:
//Il metodo scrive il contenuto d’una stringa su un file-(void) writeToTextFile: (NSString*) content{! //Cerca la cartella con i documenti! NSArray *paths = NSSearchPathForDirectoriesInDomains! (NSDocumentDirectory, NSUserDomainMask, YES);! NSString *documentsDirectory = [paths objectAtIndex:0];!! //Crea un file da scrivere nella suddetta cartella:! NSString *fileName = [NSString stringWithFormat:@"%@/info.plist", ! ! ! ! ! ! documentsDirectory];!! //salva il contenuto nella directory Documenti! [content writeToFile:fileName ! ! ! atomically:NO ! ! ! ! encoding:NSStringEncodingConversionAllowLossy ! ! ! ! error:nil];!}
Il codice inizialmente va alla ricerca della directory predefinita dei documenti col metodo NSSearchPathForDirectoriesInDomains:
Ancora sulla scritturaDopodiché indirizza il primo valore dell’array che trova
Quella è l’occorrenza della cartella definita per i documenti
Quando utilizziamo il Simulatore iPhone:
Accediamo comunque alle risorse dell’applicazione
Queste sono in /Users/<Nome>/Application Support/iPhone Simulator/<UUID dell’App>/Documents/
Utilizzare questa risorsa è fondamentale per il debug dell’App
Ancora sui Plist
Un file Plist contiene una chiave principale (“nodes”) di tipo Array
Questo array contiene diversi valori che sono dei Dizionari (“node” nel nostro caso)
All’interno del Dizionario è presente una stringa col valore
È tutto editabile con il Property List Editor di default in MacOSX
Per aprire un Plist cliccare col tasto destro e scegliere PLE.app
LetturaAnche la lettura da un file è una cosa relativamente semplice
//Questo metodo legge il contenuto del file e lo mette // in una stringa-(NSString *) displayContent{! //get the documents directory:! NSArray *paths = NSSearchPathForDirectoriesInDomains! (NSDocumentDirectory, NSUserDomainMask, YES);! NSString *documentsDirectory = [paths objectAtIndex:0];! NSString *fileName = [NSString stringWithFormat:@"%@/info.plist", ! ! ! ! ! ! documentsDirectory];! //Commentiamo questa riga perché ci serve solo a scopo didattico //NSString *content = [[NSString alloc] initWithContentsOfFile:fileName! ! ! ! ! ! ! ! ! ! ! ! ! //usedEncoding:nil! ! ! ! ! ! ! ! ! ! ! ! ! //! error:nil];!! return fileName;}
In questo caso la funzione restituisce il nome del file
Eventualmente anche una stringa col contenuto del file
Due parole anche qui
In realtà quello che si fa è recuperare il nome del file
Questo perché più avanti nel codice riempiremo un Dictionary
Il bello è che potremo iterare all’interno di valori di questo
Potremo anche specificare con più libertà i valori che ci servono
La struttura del file che salviamo è di tipo XML
Eventualmente può essere elaborata da una UIWebView
Una precisazione
In questo esempio abbiamo salvato dei files plist
Sono files di properties
Più semplici da maneggiare
Sono files XML ma molto semplici
Possono essere raccolti in NSDictionary
Possono essere inclusi all’occorrenza in NSBundles
Recuperare dei valori consoni
Ora che abbiamo creato le due routines di lettura/scrittura
Possiamo includere una nella vista principale all’apertura
L’altra nella vista in cui le informazioni devono essere viste
Nella vista info si può poi specificare che si vuole accedere al file
Nel caso in cui non sia presente la rete si prende il valore del file
Recuperare i valoriAmbedue le routine, quella in PortVC e InfoVC, hanno il metodo viewDidLoad: modificato
Nel PortViewController il codice sarà quello di connessione
La variabile di connessione è conveniente non metterla statica
Basta anche uno switch/case per cambiare la tipologia di Stringa
Poi la connessione può essere racchiusa in un metodo
In questo caso è utile sviluppare un modello come visto prima
A che punto siamo?
Abbiamo quasi finito, ci basta solo riordinare le cose
In PortViewController modifichiamo viewDidLoad:- (void)viewDidLoad {
! [super viewDidLoad];! NSURL *jsonURL = [NSURL URLWithString:@"http://tsc.prossimaisola.com/mobile/it/contenuto/all/1,4/json"];! //self.jsonData = [[NSString alloc] initWithContentsOfURL:jsonURL];! NSString *jsonData = [[NSString alloc] initWithContentsOfURL:jsonURL];! NSArray *jsonArray = [jsonData JSONValue];! [self writeToTextFile:jsonArray];! NSLog(@"Data: %@",jsonArray);}
Per semplicità ho messo l’indirizzo statico
A voi il compito di codificare tutti i vari casi :D
InfoViewController
Invece in InfoViewController.m recuperiamo i dati e stampiamo- (void)viewDidLoad { [super viewDidLoad];! !! NSString *contentOfFile = [NSString new];! contentOfFile = [self displayContent]; ! NSMutableDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:contentOfFile];! for (id key in plistDict) { NSArray *array = [plistDict objectForKey:key];! ! NSLog(@"key: %@, value: %@", key , [array objectAtIndex:0]);! ! NSLog(@"key: %@, value: %@", key , [array objectAtIndex:1]);! }! [plistDict release];}
Qui ci vuole qualche precisazione
Iteriamo sulla chiave e visualizziamo i valori
Ancora su chiave/valore
Per prendere il determinato valore alla chiave “title”
Possiamo ulteriormente iterare sul Dizionario
E col metodo valueForKey:@”title” possiamo ottenere quel che ci serve
Una volta ottenuta l’Array di stringhe è sufficiente passarla al metodo cellForRowAtIndexPath:
Fatto questo si visualizza correttamente il valore
Infine
Ricordiamoci anche di modificare il metodo numbersOfRowAtIndexPath:
Di passare [nomedellArray count]; per indicare le righe
Un suggerimento:
Utilizzo di NSEnumerator
Essenzialmente quelli che si usano nel mondo dei DB
Riepilogo
Abbiamo creato due funzioni una per scrivere una per leggere
Le informazioni che c’interessano sono in viewDidLoad:
In un caso nella view che si apre all’inizio del ciclo di vita dell’app
Nell’altro nella view che ci serve per visualizzare i messaggi
Si può implementare un meccanismo di lettura se manca la rete
In caso contrario si fa una nuova richiesta
LAYAR SDK
Cos’è Layar
È un tool per la realtà aumentata per iPhone e Android
L’azienda fornisce l’applicazione in maniera totalmente free
Funziona con dei livelli che possono essere caricati nel programma
C’è una sorta di Store che consente di scaricare nuovi livelli
Basta scegliere i livelli che c’interessano e caricarli
Perché è fico?
Molte aziende lo usano con successo per promuovere i propri prodotti
Ci sono diversi tipi di modi per lavorare con Layar
Prima cosa è necessario che gli sviluppatori creino un layer
Questo layer può essere 2D o 3D
In esso si possono indicare dei POI (Points of Interests) su una mappa
Altre caratteristiche
A differenza di tool come ReactiVision o simili
Layar ha sempre un riferimento geolocalizzato delle informazioni
È comunque sempre necessario che il programma (Player) s’interfacci con la rete ed il segnale GPS
Non supporta nativamente il riconoscimento di tags
Può essere integrato all’interno di un’applicazione esistente
Come funziona con iPhone
Fortunatamente per iPhone Layar fornisce un SDK
L’SDK va scaricato dal sito Web degli sviluppatori
Consiste in una serie di classi molto semplici
Tipicamente si richiama una view di Layer con modalView
Poi qualcuno s’incaricherà di rilasciare modalViewController quando questa non serve più
Configurare l’account devEntriamo in http://www.layar.com/publishing/signup/acceptterms/developer/?next=/publishing/
Ci registriamo come Developers
Dopodiché definiamo un nuovo Layer Dummy
Io ho inserito dei finti URL e un nome indicativo
Attivare l’autenticazione OAuth
Inserire password e nome utente scelto ad hoc
Prima di testare il layer
Prima di testare il nostro layer nel Layer Player
Verificare i seguenti parametri di connessione
Nome Layer
OAuth Consumer Key
OAuth Consumer Secret
Ora possiamo scaricare l’SDK
Next Step
È necessario ora scaricare l’SDK dal sito di Layar
Per importarlo nel progetto il solito Add->Existing Files...
Ora come abbiamo visto nel caso di JSON basta aggiungere il player al progetto
È ora possibile interagire con le classi per aprire un controller
Vediamo il codice che serve per aprire una view modale
Codice d’esempio
#import <LayarPlayer.h>! NSString *layerName =@"pippo"; ! NSString *consumerKey =@"user"; ! NSString *consumerSecret =@"password";! NSArray *oauthKeys = [NSArray arrayWithObjects:LPConsumerKeyParameterKey, LPConsumerSecretParameterKey, nil];! NSArray *oauthValues = [NSArray arrayWithObjects:consumerKey, consumerSecret, nil];! NSDictionary *oauthParameters = [NSDictionary dictionaryWithObjects:oauthValues forKeys:oauthKeys];! NSArray *layerKeys = [NSArray arrayWithObject:@"radius"]; ! NSArray *layerValues = [NSArray arrayWithObject:@"1000"]; ! NSDictionary *layerFilters = [NSDictionary dictionaryWithObjects:[layerValues forKeys:layerKeys];! LPAugmentedRealityViewController *augmentedRealityViewController = [[[ LPAugmentedRealityViewController alloc] init] autorelease];! augmentedRealityViewController.delegate = self; ! [self presentModalViewController:augmentedRealityViewController animated:YES]; ! [augmentedRealityViewController loadLayerWithName:layerName ! ! ! ! ! ! ! ! ! oauthParameters:oauthParameters ! ! ! ! ! ! ! ! ! layerFilters:layerFilters options:LPMapViewDisabled | LPListViewDisabled];
Due commenti
La classe principale è LPAugmentedRealityViewController
Questa classe non è altro che un view controller
Come “NIB” sostanzialmente passiamo un layer
E i parametri di autenticazione tramite OAuth
Gli altri sono parametri abbastanza comprensibili
Possiamo personalizzare il layer tramite il sito di Layar
Precisazioni
Per semplicità il codice è condensato
Come al solito si può definire un modello e chiamare queste funzioni all’interno di un modello
In questo caso non è necessario definire una view
La view è già configurata in maniera programmatica dalla libreria
Sarà semplicemente necessario istanziare la classe
Commenti
http://www.layar.com/publishing/testpage/page/pippo/
Serve questa pagina per inserire POI (Point of Interests)
Una volta pronto il layer si può inviare al revisore per la convalida
Request for Approval è il bottone da cliccare
I layar si possono fare free oppure a pagamento
THREE20
Cos’è Three20
Three20 è una libreria per iOS
Parte dallo sviluppo della prima applicazione di FaceBook
Contiene una marea di classi già pronte
In più contiene anche una marea di esempi
Per ogni esempio viene svelata una funzionalità specifica
Il progetto è molto vasto ed in una fase decisamente matura
Chi la usa?
Come al solito il tasso di popolarità è direttamente proporzionale alla maturità
Gran parte delle parte delle applicazioni che si basano su AppKit
Contiene veramente centinaia di controlli alcuni anche nuovi
Sono molto semplici da manipolare e facilitano la scrittura dell’app
Per citarne uno il famoso Release to update
Features
Essendo Open Source abbiamo anche la possibilità di estenderlo
Nel sito Three20.info ci sono anche altre estensioni
Basta comuque prendere spunto dagli esempi per diventare subito operativi
Vediamo un po’ come configurare il tutto
Partiamo dall’importazione nel progetto della libreria
Aggiungere Three20
È possibile includere Three20 tramite un semplice script python
python three20/src/scripts/ttmodule.py -p path/to/myProject.xcodeproj Three20
Automaticamente tutti i moduli vengono importati
Si può anche utilizzare il vecchio metodo
Ci sono dei problemi con le librerie condivise
Conviene usare i flag -all_load e -ObjC
Launcher
Launcher è forse il controllo più bello messo a disposizone
È compatibile con iPhone e iPad
È utilizzato già da un’infinità di App (iSpazio.net ad esempio)
Il modo più semplice per utilizzarlo è fare riferimento all relativo oggetto chiamato TTLauncherViewController
Possiamo definire una classe che erediti da questo
BasicLauncherViewController
Ecco come dovrà apparire il file header di classe:#import <Three20Launcher/Three20Launcher.h> @interface BasicLauncherViewController : TTLauncherViewController {} @end
Mi sembra che non sia necessario a questo punto nessun chiarimento...
BasicLauncherViewController
Invece il file d’implementazione è leggermente più complesso:#import "BasicLauncherViewController.h"
@implementation BasicLauncherViewController - (void)viewDidLoad { [super viewDidLoad]; TTLauncherItem* item = [[TTLauncherItem alloc] initWithTitle: @"Item title" image: @"bundle://Icon.png" URL: nil]; [self.launcherView addItem:item animated:NO]; TT_RELEASE_SAFELY(item);} @end
Scherzavo! Basta definire il launcher ed inizializzarlo
TTRELEASE_
La nostra bellissima libreria s’incarica anche di rilasciare gli oggetti ormai non più utilizzati
Tramite delle Macro, il rilascio avviene in maniera sicura
Quante volte è capitato di vedere crashare un programma per questo motivo
Nella documentazione è definita anche questa funzionalità
Chicca finale
Three20 include anche un parser JSON molto performante
Si chiama YAJL ed è scritto in C
Qui è stato scritto un wrapper completamente in Objective-C
È anche presente il nostro SBJSONParser
Inoltre ci sono una serie infinita di aggiunte alle classi standard
Bisognerà chiamare le nuove classi col prefisso TT*
The end
Anche per oggi abbiamo finito
Queste slide saranno disponibili sul sito entro oggi
http://sites.google.com/a/prossimaisola.com/ios/
Per qualsiasi bug fare una richiesta per il sito
Mettiamo il bug a disposizione di tutti e vediamo chi lo risolve prima
ALLA PROSSIMA LEZIONE!