Introduzione a JSONModel

Cos'è JSONModel?

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.

Caratteristiche di base

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.

Mappatura automatica di classi da JSON a modello

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.

Input Validation

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.

Trasformazione dei dati

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.

Modelli annidati

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.

L'app Hello Chuck

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:

Passaggio 1: Impostazione del progetto

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.

Passaggio 2: creare classi di modelli

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;
  1. TagModel è il protocollo che hai dichiarato un momento fa. Dice JokeModel che la serie di tag dovrebbe contenere istanze di TagModel classe.
  2. Aderendo al 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ò.

Passaggio 3: Visualizza la configurazione del controller

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 schermo
  • scherzi 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.

Passaggio 4: recuperare JSON e creare oggetti modello

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?

  1. [JokeModel arrayOfModelsFromData: errore:] prende i dati JSON e li trasforma in una serie di oggetti JSON.
  2. Poi JokeModel loop su quegli oggetti e crea JokeModel istanze da ciascun oggetto JSON.
  3. Ogni JokeModel l'istanza controlla i dati JSON ricevuti e inizializza le sue proprietà con i valori corretti.
  4. Se la 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];);

Passaggio 5: visualizzazione delle battute

- (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.

Passaggio 6: personalizzazione dei modelli

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.

Conclusione

Ora hai una conoscenza di base della libreria JSONModel. Finora, hai imparato:

  • come creare una semplice classe di modelli che eredita da JSONModel
  • come definire le proprietà obbligatorie e facoltative
  • e come nidificare le classi di modelli

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.