I nostri dispositivi iOS sono collegati a Internet il più delle volte e, naturalmente, la maggior parte delle app sui nostri dispositivi si connettono a un server remoto per afferrare questo o quel blocco di dati ogni tanto.
Alcune app consumano solo un po 'di dati, recuperando solo le ultime notizie ogni ora o così. Altre app interagiscono molto con un servizio di back-end mentre l'utente sfoglia il loro social feed, legge i post e carica le foto.
I giorni in cui ogni servizio Web parlava XML sono finiti da tempo. Oggigiorno, la maggior parte delle applicazioni mobili comunica con i servizi Web utilizzando JSON. Se hai intenzione di creare un'applicazione mobile che dialoga con un back-end remoto, è probabile che dovrai essere in grado di inviare e ricevere JSON.
JSONModel è una libreria open source scritta in Objective-C, che aiuta a recuperare JSON da un server, analizzarlo e inizializzare le classi del modello con i dati. Convalida anche i dati JSON, le cascate tramite modelli annidati e altro ancora.
"Ma aspetta!" potresti pensare "Ho già scritto un'app per iPhone che recupera alcuni JSON e li mostra sullo schermo, è stato piuttosto facile!"
Bene, questo è parzialmente vero. NSJSONSerialization
è disponibile da iOS 5, quindi è davvero piuttosto semplice convertire una risposta JSON in una NSDictionary
oggetto. Funziona bene per applicazioni semplici, ma credetemi quando dico che questa non è una buona idea per un'applicazione complessa con un modello di dati complesso. Vediamo come JSONModel può salvare il tuo bacon.
Nota che sono l'autore di JSONModel, lo sviluppo e il mantenimento della libreria con l'aiuto dei contributori su GitHub. Sono ovviamente di parte, ma questa è una buona notizia per te dato che sarai in grado di imparare dalla persona che ha creato la libreria.
In questa sezione, evidenzierò brevemente e discuterò le caratteristiche di base della libreria. Se sei troppo ansioso di tuffarti nel codice, passa alla sezione successiva, L'app Hello Chuck.
Quando si guardano i dati JSON che popolano l'oggetto del modello, si ha spesso la tendenza a far corrispondere i nomi delle chiavi utilizzate nei dati JSON. Finisci per scrivere codice simile a questo:
self.firstName = [json objectForKey: @ "firstName"]; self.familyName = [json objectForKey: @ "familyName"]; self.age = [json objectForKey: @ "age"];
Con JSONModel, non è necessario scrivere questo tipo di codice boilerplate. JSONModel associa automaticamente JSON alle proprietà della classe del modello.
JSONModel controlla automaticamente le proprietà della classe del modello e garantisce che il JSON utilizzato per inizializzare un oggetto modello corrisponda alla definizione della classe del modello. In caso di mancata corrispondenza, l'oggetto modello non verrà inizializzato.
Inoltre, il modello verifica che i dati JSON corrispondano ai tipi definiti dalla classe del modello. Se ottieni una matrice invece di una stringa, ad esempio, i dati JSON sono considerati non validi.
Grazie alle semplici specifiche di JSON, è facile da usare, ma rimuove anche molti metadati quando viene utilizzato per trasferire dati da un back-end a un client e viceversa. Un oggetto JSON può contenere solo stringhe, numeri, matrici e oggetti.
Nella classe del modello Objective-C, di solito si hanno proprietà di vari tipi, non limitate a stringhe e numeri, che sono gli unici tipi di dati supportati da JSON. Ad esempio, hai spesso URL in un oggetto JSON. È facile convertire una stringa in un oggetto JSON in un NSURL
oggetto, ma la parte fastidiosa è che è necessario farlo da soli.
JSONModel consente di definire una volta le trasformazioni per i tipi di dati e di utilizzarli nei modelli. Ad esempio, se una risposta JSON ti fornisce una data come data e ora sotto forma di numero intero, devi solo dire a JSONModel come convertire il numero intero in un NSDate
oggetto una volta Imparerai di più sulle trasformazioni dei dati nella seconda parte di questa serie.
Più spesso, una risposta JSON ha una struttura complessa. Un oggetto, ad esempio, può contenere uno o più altri oggetti. Dai un'occhiata al seguente oggetto JSON.
"id": 10, "more": "text": "ABC", "count": 20
JSONModel consente di nidificare anche classi di modelli. Non importa se il tuo modello contiene un altro modello o un array di oggetti modello, JSONModel ispeziona le classi del modello e inizializza automaticamente gli oggetti del tipo corretto. Daremo un'occhiata più da vicino ai modelli annidati un po 'più tardi.
Questa è una teoria sufficiente per ora. Impariamo come utilizzare la libreria JSONModel creando un'applicazione di esempio semplice.
Ora che hai un'idea di base su cosa fa JSONModel, svilupperai una semplice app che recupera un feed JSON delle battute di Chuck Norris e le mostra all'utente una alla volta. Al termine, l'app sarà simile a questa:
Avvia Xcode 5, crea un nuovo progetto selezionando Nuovo> Progetto ... dal File menu e selezionare Applicazione vista singola modello dalla lista di Applicazione iOS modelli.
Assegna un nome al progetto HelloChuck, indica a Xcode dove desideri salvarlo e premi Creare. Non è necessario mettere il progetto sotto il controllo del codice sorgente.
Successivamente, scarica l'ultima versione della libreria JSONModel da GitHub, decomprimi l'archivio e ottieni un picco all'interno.
L'archivio contiene applicazioni demo per iOS e OSX, test unitari e altro. Ti interessa solo la cartella denominata JSONModel. Trascinalo sul tuo progetto Xcode. L'installazione è ancora più semplice se usi CocoaPods.
Il feed JSON che utilizzerai è piuttosto semplice. Contiene una serie di barzellette, con ogni scherzo che ha un ID, lo scherzo stesso e, opzionalmente, una serie di tag.
"id": 7, "text": "C'era una strada che prende il nome da Chuck Norris ma è stata cambiata perché nessuno incrocia Chuck Norris e vive", "tag": ["id": 1, "tag" : "lethal", "id": 2, "tag": "new"]
Iniziamo creando le classi del modello per abbinare i dati JSON. Crea una nuova classe, JokeModel
, e farlo ereditare da JSONModel
. Inserisci id
e testo
proprietà per abbinare le chiavi nei dati JSON in questo modo:
@interface JokeModel: JSONModel @property (assign, nonatomic) int id; @property (strong, nonatomic) NSString * text; @fine
La libreria JSONModel convertirà automaticamente i numeri in modo che corrispondano al tipo di proprietà.
È inoltre necessario creare una classe per gli oggetti tag nei dati JSON. Crea una nuova classe, TagModel
, e farlo ereditare JSONModel
. Dichiarare due proprietà id
e etichetta
di tipo NSString
. Il TagModel
la classe dovrebbe assomigliare a questa:
@interface TagModel: JSONModel @property (strong, nonatomic) NSString * id; @property (strong, nonatomic) tag NSString *; @fine
Nota che hai impostato il tipo di id
a NSString
. JSONModel sa perfettamente come trasformare i numeri in stringhe, gestirà la trasformazione per te. L'idea è che hai solo bisogno di concentrarti sui dati che ti servono nella tua applicazione, senza doversi preoccupare di come appaiono i dati JSON.
Anche se il TagModel
la classe è pronta per l'uso, è necessario un modo per dire al JokeModel
classe che la chiave tag
contiene un elenco di TagModel
le istanze. Questo è molto facile da fare con JSONModel. Aggiungi un nuovo protocollo vuoto in TagModel.h e chiamalo TagModel
:
@protocol TagModel @end
Aperto JokeModel.h e importa il file di intestazione del file TagModel
classe:
#import "TagModel.h"
Ecco la magia. Dichiarare una nuova proprietà a JokeModel
come mostrato di seguito. Il tag
la proprietà è di tipo NSArray
e si conforma a due protocolli.
@property (strong, nonatomic) NSArray* tag;
TagModel
è il protocollo che hai dichiarato un momento fa. Dice JokeModel
che la serie di tag dovrebbe contenere istanze di TagModel
classe.Opzionale
protocollo, il JokeModel
class sa che i dati JSON non conterranno sempre un elenco di tag.Questo è un buon momento per sottolineare che ogni proprietà nella classe del modello è predefinita necessario. Se id
o testo
mancano nei dati JSON, l'inizializzazione del JokeModel
l'oggetto fallirà. Tuttavia, se tag
sono assenti per un particolare scherzo, JSONModel non si lamenterà di ciò.
Per prima cosa devi fare un paio di aggiustamenti al ViewController
classe. Aprire ViewController.m e, sotto la dichiarazione di importazione esistente nella parte superiore, importare il file JokeModel
classe:
#import "JokeModel.h"
È necessario aggiungere due proprietà alla classe ViewController:
etichetta
per visualizzare il testo dello scherzo sullo schermoscherzi
per memorizzare la serie di battute@interface ViewController () @property (strong, nonatomic) Etichetta UILabel *; @property (strong, nonatomic) scherzi NSArray *; @fine
È inoltre necessario impostare l'etichetta in modo che sia pronta quando si recuperano i dati JSON e si è pronti a visualizzare uno scherzo. Aggiorna il viewDidLoad
metodo come mostrato di seguito.
- (void) viewDidLoad [super viewDidLoad]; self.label = [[UILabel alloc] initWithFrame: self.view.bounds]; self.label.numberOfLines = 0; self.label.textAlignment = NSTextAlignmentCenter; self.label.alpha = 0; [self.view addSubview: self.label]; [self fetchJokes];
Tu crei a UILabel
ad esempio la dimensione dello schermo del dispositivo e l'hai impostato alfa
proprietà a 0
. L'etichetta è nascosta fino a quando il primo scherzo è pronto per essere visualizzato.
Nell'ultima riga di viewDidLoad
, chiami fetchJokes
, in cui l'applicazione recupera i dati JSON remoti e ne memorizza i contenuti nel controller della vista scherzi
proprietà. Implementerai fetchJokes
in un attimo.
In questo esempio, utilizzerai il NSURLSession
classe per recuperare i dati JSON remoti. Si crea l'URL per la richiesta, si inizializza un'attività di dati e la si invia per la sua strada.
- (void) fetchJokes NSURL * jokesUrl = [NSURL URLWithString: @ "https://s3.amazonaws.com/com.tuts.mobile/jokes.json"]; [[[NSURLSession sharedSession] dataTaskWithURL: jokesUrl completionHandler: ^ (dati NSData *, risposta NSURLResponse *, errore NSError *) // gestisce i dati qui] riprendi];
dataTaskWithURL: completionHandler:
crea per un NSURLSessionDataTask
istanza con l'URL che gli viene passato. A chiamata curriculum vitae
sull'attività dati, dite al NSURLSession
istanza per aggiungere l'attività dati alla sua coda.
Successivamente, è necessario aggiungere il codice per inizializzare il JokeModel
le istanze. Sostituire // gestire i dati qui
con:
self.jokes = [JokeModel arrayOfModelsFromData: errore di dati: nil];
arrayOfModelsFromData: errore:
prende un NSData
oggetto da una risposta JSON e restituisce una serie di modelli. Ma cosa succede sotto il cofano?
[JokeModel arrayOfModelsFromData: errore:]
prende i dati JSON e li trasforma in una serie di oggetti JSON.JokeModel
loop su quegli oggetti e crea JokeModel
istanze da ciascun oggetto JSON.JokeModel
l'istanza controlla i dati JSON ricevuti e inizializza le sue proprietà con i valori corretti.JokeModel
l'istanza trova il contenuto nei dati tag
chiave, quindi crea una matrice di TagModel
istanze dal valore associato al tag
chiave.Se hai solo bisogno di creare un'istanza di modello, allora initWithData:
e initWithString:
sono i metodi che devi usare. Daremo un'occhiata più da vicino a questi metodi nel prossimo tutorial.
Dopo aver inizializzato la serie di barzellette, puoi visualizzare il primo scherzo all'utente utilizzando il seguente frammento di codice.
dispatch_async (dispatch_get_main_queue (), ^ [self showNextJoke];);
- (void) showNextJoke JokeModel * model = self.jokes [arc4random ()% self.jokes.count]; NSString * tags = model.tags? [Model.tags componentsJoinedByString: @ ","]: @ "nessun tag"; self.label.text = [NSString stringWithFormat: @ "% i.% @ \ n \ n% @", model.id, model.text, tags]; [UIView animateWithDuration: 1.0 animazioni: ^ self.label.alpha = 1.0; completamento: ^ (BOOL terminato) [self performSelector: @selector (hideJoke) withObject: nil afterDelay: 5.0]; ];
Per prima cosa tiri uno scherzo a caso dal scherzi
array e memorizzarlo modello
. Se lo scherzo contiene tag, li si memorizza come elenco separato da virgole in una variabile denominata tag
. Se lo scherzo non ha tag, si imposta tag
a @ "nessun tag"
.
Si aggiorna l'etichetta per mostrare il id
, testo
, e tag
dello scherzo corrente e utilizzare un'animazione dissolvenza per mostrare lo scherzo all'utente.
Al termine dell'animazione, attendi cinque secondi prima di richiamare hideJoke
, che nasconde lo scherzo con un'altra animazione dissolvenza. Al termine dell'animazione, chiami showNextJoke
di nuovo.
- (void) hideJoke [UIView animateWithDuration: 1.0 animazioni: ^ self.label.alpha = 0.0; completamento: ^ (BOOL terminato) [self showNextJoke]; ];
Questo crea un ciclo infinito, dissolvendo le battute selezionate in modo casuale dentro e fuori. L'effetto è abbastanza forte. Fare un tentativo eseguendo l'applicazione.
Tuttavia, c'è il problema che visualizza la matrice di tag TagModel
oggetti invece di oggetti stringa. Questo comportamento è in realtà una funzionalità della libreria JSONModel. Crea automaticamente una descrizione dell'oggetto come quella che hai visto nella schermata precedente. Elenca le proprietà dell'oggetto modello e i relativi valori, il che aiuta molto con il debug.
Per completare questo tutorial, scriverete la prima riga del codice del modello. Modelli che ereditano da JSONModel
sono come qualsiasi altra classe Objective-C. Ciò significa che è possibile ignorare i metodi di JSONModel
e personalizza il loro comportamento come preferisci.
Aperto TagModel.m e sovrascrive il metodo di descrizione predefinito:
- (NSString *) description return self.tag;
Quando ora chiami componentsJoinedBySeparator:
sulla serie di tag, invece della descrizione predefinita di TagModel
otterrai il tag solo come testo normale.
Fare un tentativo eseguendo l'applicazione ancora una volta. Ora dovresti vedere l'elenco dei tag esattamente sotto ogni scherzo.
Ora hai una conoscenza di base della libreria JSONModel. Finora, hai imparato:
JSONModel
In questo breve tutorial, ho solo toccato alcune delle funzionalità di JSONModel
biblioteca. Nelle prossime puntate di questa serie, imparerai di più sulla trasformazione dei dati, lavorando con le API JSON remote e esaminerai alcune funzionalità di JSONModel più avanzate.