Komme i gang med JSONModel

Hva er JSONModel?

Våre iOS-enheter er koblet til Internett mesteparten av tiden, og de fleste appene på enhetene våre kobler selvfølgelig til en ekstern server for å hente denne eller den lille delen av data hver eneste gang.

Noen apps bruker bare litt data, bare henter de siste overskriftene hver time eller så. Andre apper samhandler mye med en backend-tjeneste mens brukeren gjennomsøker sin sosiale feed, leser gjennom innlegg og laster opp bilder.

Dagene at hver webtjeneste snakket XML er langt borte. I dag kommuniserer de fleste mobile applikasjoner med webtjenester ved hjelp av JSON. Hvis du planlegger å lage et mobilprogram som snakker til en ekstern backend, er det sjansen for at du må kunne sende og motta JSON.

JSONModel er et åpen kildebibliotek som er skrevet i Objective-C, som hjelper deg med å hente JSON fra en server, analysere det og initialisere modellklassene dine med dataene. Det validerer også JSON-data, kaskader gjennom nestede modeller og mer.

"Men vent!" du kan tenke "Jeg skrev allerede en iPhone app som henter noe JSON og viser det på skjermen. Det var ganske enkelt!"

Vel, det er delvis sant. NSJSONSerialization har vært tilgjengelig siden iOS 5, så det er ganske enkelt ganske enkelt å konvertere et JSON-svar til en NSDictionary gjenstand. Dette fungerer fint for enkle applikasjoner, men tro meg når jeg sier at dette ikke er en god ide for et komplekst program med en kompleks datamodell. La oss se hvordan JSONModel kan lagre baconet ditt.

Merk at jeg er forfatter av JSONModel, utvikle og vedlikeholde biblioteket ved hjelp av bidragsytere på GitHub. Jeg er åpenbart partisk, men dette er gode nyheter for deg som du vil kunne lære av personen som opprettet biblioteket.

Grunnleggende funksjoner

I denne delen vil jeg kortlegge og diskutere de grunnleggende funksjonene i biblioteket. Hvis du er for ivrig etter å dykke inn i kode, hopper du over til neste del, Hello Chuck App.

Automatisk kartlegging av JSON til modellklasser

Når du ser på JSON-dataene som fyller modellobjektet, føler du deg ofte tilbøyelig til å matche navnene på tastene som brukes i JSON-dataene. Du ender opp med å skrive kode som ser slik ut:

self.firstName = [json objectForKey: @ "firstName"]; self.familyName = [json objectForKey: @ "familyName"]; self.age = [json objectForKey: @ "age"];

Med JSONModel trenger du ikke å skrive denne typen boilerplate-kode. JSONModel karter automatisk JSON til egenskapene til modellklassen.

Inngangsvalidering

JSONModel inspiserer automatisk egenskapene til modellklassen din og sikrer at JSON som brukes til å initialisere et modellobjekt, stemmer overens med modellklassdefinisjonen. Hvis det er en feilmatch, blir ikke modellen objektet initialisert.

I tillegg verifiserer modellen at JSON-dataene samsvarer med typene som er definert av modellklassen. Hvis du får en matrise i stedet for en streng, anses JSON-dataene som ugyldige.

Datatransformasjon

På grunn av JSONs enkle spesifikasjon er det enkelt å bruke, men det fjerner også mye metadata når det brukes til å overføre data fra en backend til en klient og omvendt. Et JSON-objekt kan bare inneholde strenge, tall, arrays og objekter.

I objektiv-C-modellen har du vanligvis egenskaper av ulike typer, ikke begrenset til strenge og tall, som er de eneste datatypene som støttes av JSON. For eksempel har du ofte nettadresser i et JSON-objekt. Det er enkelt å konvertere en streng i et JSON-objekt til en NSURL objekt, men den irriterende delen er at du trenger å gjøre dette selv.

JSONModel la oss definere transformasjoner for datatyper en gang og bruke dem på tvers av modellene dine. Hvis en JSON-respons for eksempel gir deg en dato som tidsstempel i form av et heltall, må du bare fortelle JSONModel hvordan du konverterer heltallet til en NSDate objekt en gang. Du lærer mer om datatransformasjoner i den andre delen av denne serien.

Nestede modeller

Oftere enn ikke, har en JSON-respons en kompleks struktur. Et objekt kan for eksempel inneholde en eller flere andre objekter. Ta en titt på følgende JSON-objekt.

"id": 10, "mer": "tekst": "ABC", "count": 20 

JSONModel, la oss også få rede på nestmodellklasser. Det spiller ingen rolle om modellen din inneholder en annen modell eller en rekke modellobjekter, JSONModel inspiserer modellklassene og initierer automatisk objekter av riktig type. Vi tar en nærmere titt på nestede modeller litt senere.

Det er nok teori for nå. La oss lære å bruke JSONModel-biblioteket ved å lage et enkelt, prøveprogram.

Hello Chuck App

Nå som du har en grunnleggende ide hva JSONModel gjør, vil du utvikle en enkel app som henter en JSON-feed av Chuck Norris vitser og viser dem til brukeren en etter en. Når du er ferdig, ser appen noe ut som dette:

Trinn 1: Prosjektoppsett

Start Xcode 5, opprett et nytt prosjekt ved å velge Nytt> Prosjekt ... fra Fil menyen, og velg Enkeltvisningsprogram mal fra listen over iOS-applikasjon maler.

Gi navnet navnet på prosjektet HelloChuck, Fortell Xcode hvor du vil lagre den, og klikk Skape. Det er ikke nødvendig å sette prosjektet under kildekontroll.

Deretter laster du ned den nyeste versjonen av JSONModel-biblioteket fra GitHub, pakker ut arkivet og har en topp inne.

Arkivet inneholder demo-applikasjoner for iOS og OSX, enhetstester og mer. Du er bare interessert i mappen som heter JSONModel. Dra den til ditt Xcode-prosjekt. Installasjonen er enda enklere hvis du bruker CocoaPods.

Trinn 2: Opprett modellklasser

JSON-fôret du skal bruke er ganske enkelt. Den inneholder en rekke vitser, med hver vits å ha et id, vitsen selv, og, eventuelt, en rekke koder.

"id": 7, "text": "Det pleide å være en gate oppkalt etter Chuck Norris, men den ble endret fordi ingen krysser Chuck Norris og lever", "tags": ["id": 1, "tag" : "dødelig", "id": 2, "tag": "nytt"]

La oss begynne med å lage modellklassen for å matche JSON-dataene. Lag en ny klasse, JokeModel, og gjør det arv fra JSONModel. Legg til id og tekst egenskaper som samsvarer med tastene i JSON-dataene slik:

@interface JokeModel: JSONModel @property (tilordne, ikkeatomisk) int id; @property (strong, nonatomic) NSString * tekst; @slutt

JSONModel-biblioteket konverterer automatisk tall for å matche egenskapens type.

Du må også opprette en klasse for taggenobjektene i JSON-dataene. Lag en ny klasse, TagModel, og gjør det arv JSONModel. Erklære to egenskaper id og stikkord av type NSString. De TagModel klassen skal se slik ut:

@interface TagModel: JSONModel @property (sterk, ikkeatomisk) NSString * id; @property (strong, nonatomic) NSString * tag; @slutt

Legg merke til at du har angitt typen av id til NSString. JSONModel vet helt fint hvordan man forvandler tall til strenger, det vil håndtere transformasjonen for deg. Tanken er at du bare trenger å fokusere på dataene du trenger i søknaden din uten å måtte bekymre deg for hva JSON-dataene ser ut som.

Selv om TagModel klassen er klar til bruk, du trenger en måte å fortelle JokeModel klasse som nøkkelen tags inneholder en liste over TagModel forekomster. Dette er veldig enkelt å gjøre med JSONModel. Legg til en ny tom protokoll i TagModel.h og ring det TagModel:

@protocol TagModel @end

Åpen JokeModel.h og importer headerfilen til TagModel klasse:

#import "TagModel.h"

Her kommer den magiske. Erklære en ny eiendom til JokeModel som vist nedenfor. De tags Eiendommen er av typen NSArray og det samsvarer med to protokoller.

@property (sterk, ikkeatomisk) NSArray* tagger;
  1. TagModel er protokollen du erklærte for et øyeblikk siden. Det forteller JokeModel at arrayet av koder skal inneholde forekomster av TagModel klasse.
  2. Ved å følge til Valgfri protokoll, den JokeModel klassen vet at JSON-dataene ikke alltid vil inneholde en liste over tagger.

Dette er et godt øyeblikk å understreke at hver eiendom i modellklassen din er som standard nødvendig. Hvis id eller tekst mangler i JSON data, initialiseringen av JokeModel objektet vil mislykkes. Men hvis tags er fraværende for en bestemt vits, vil JSONModel ikke klage over det.

Trinn 3: Se kontrolleroppsett

Du må først gjøre noen tilpasninger til ViewController klasse. Åpne opp ViewController.m og, under den eksisterende importerklæringen øverst, importerer JokeModel klasse:

#import "JokeModel.h"

Du må legge til to egenskaper til ViewController-klassen:

  • merkelapp for å vise spøkens tekst på skjermen
  • vitser å lagre rekke vitser
@interface ViewController () @property (sterk, ikkeatomisk) UILabel * etikett; @property (strong, nonatomic) NSArray * vitser; @slutt

Du må også sette opp etiketten slik at den er klar når du henter JSON-dataene og har en vits klar til å bli vist. Oppdater viewDidLoad metode som vist nedenfor.

- (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]; [selvfetchjokes]; 

Du oppretter en UILabel Installer størrelsen på enhetens skjerm, og du angir at den er alfa eiendom til 0. Etiketten er skjult til den første vitsen er klar til å bli vist.

I den siste linjen av viewDidLoad, du ringer fetchJokes, der søknaden henter de eksterne JSON-dataene og lagrer innholdet i visningsregulatorens vitser eiendom. Du skal implementere fetchJokes på et øyeblikk.

Trinn 4: Hent JSON og opprett modellobjekter

I dette eksemplet bruker du NSURLSession klassen for å hente de eksterne JSON-dataene. Du oppretter nettadressen for forespørselen, initierer en dataoppgave, og sender den på vei.

- (void) fetchJokes NSURL * jokesUrl = [NSURL URLWithString: @ "https://s3.amazonaws.com/com.tuts.mobile/jokes.json"]; [[[NSURLSession sharedSession] dataTaskWithURL: jokesUrl completionHandler: ^ (NSData * data, NSURLResponse * respons, NSError * feil) // håndter data her] CV];  

dataTaskWithURL: completionHandler: skaper for en NSURLSessionDataTask forekomst med nettadressen som er sendt til den. Ved å ringe gjenoppta På dataoppgaven, forteller du NSURLSession eksempel for å legge til dataoppgaven i køen.

Deretter må du legge til koden for å initialisere JokeModel forekomster. Erstatte // håndter data her med:

self.jokes = [JokeModel arrayOfModelsFromData: datafeil: null];

arrayOfModelsFromData: error: tar en NSData objekt fra en JSON-respons og returnerer en rekke modeller. Men hva skjer under hetten?

  1. [JokeModel arrayOfModelsFromData: error:] tar JSON-dataene og gjør det til en rekke JSON-objekter.
  2. Deretter JokeModel løkker over disse objektene og skaper JokeModel forekomster fra hvert JSON-objekt.
  3. Hver JokeModel instans inspiserer JSON-dataene den mottar, og initierer sine egenskaper med de riktige verdiene.
  4. Hvis JokeModel forekomsten finner innhold i dataene tags nøkkel, så skaper det en rekke TagModel forekomster av verdien knyttet til tags nøkkel.

Hvis du bare trenger å opprette en modelleksempel, da initWithData: og initWithString: er metodene du trenger å bruke. Vi vil se nærmere på disse metodene i neste veiledning.

Etter at du har initialisert rekke vitser, kan du vise den første vitsen til brukeren ved hjelp av følgende kodestykke.

dispatch_async (dispatch_get_main_queue (), ^ [self showNextJoke];);

Trinn 5: Viser vitser

- (void) showNextJoke JokeModel * model = self.jokes [arc4random ()% self.jokes.count]; NSString * tags = model.tags? [Model.tags componentsJoinedByString: @ ","]: @ "no tags"; self.label.text = [NSString stringWithFormat: @ "% i.% @ \ n \ n% @", model.id, model.text, tags]; [UIView animateWithDuration: 1.0 animasjoner: ^ self.label.alpha = 1.0;  fullføring: ^ (BOOL ferdig) [self performSelector: @selector (hideJoke) withObject: nil afterDelay: 5.0]; ]; 

Du trekker først en tilfeldig spøk fra vitser array og lagre den i modell. Hvis vitsen har koder, lagrer du dem som en kommaseparert liste i en variabel som heter tags. Hvis vitsen ikke har noen koder, setter du inn tags til @ "no tags".

Du oppdaterer etiketten for å vise id, tekst, og tags av den nåværende vitsen og bruk en falsk animasjon for å vise vitsen til brukeren.

Når animasjonen er fullført, venter du fem sekunder før du påkaller hideJoke, som gjemmer vitsen med en annen falsk animasjon. Når animasjonen er fullført, ringer du showNextJoke igjen.

- (void) hideJoke [UIView animateWithDuration: 1.0 animasjoner: ^ self.label.alpha = 0.0;  fullføring: ^ (BOOL ferdig) [self showNextJoke]; ]; 

Dette skaper en uendelig loop, fading tilfeldig utvalgte vitser inn og ut. Effekten er ganske kult. Prøv det ved å kjøre programmet.

Imidlertid er det problemet at utskrift av arrayet av koder vises TagModel objekter i stedet for strengobjekter. Denne oppførselen er faktisk en funksjon av JSONModel-biblioteket. Den oppretter automatisk en beskrivelse av objektet som det du så i forrige skjermbilde. Den viser modellobjektets egenskaper og deres verdier, noe som virkelig hjelper med feilsøking.

Trinn 6: Tilpasse modeller

For å pakke inn denne opplæringen, skal du skrive din første linje med modellkode. Modeller som arver fra JSONModel er akkurat som alle andre Objective-C-klasser. Dette betyr at du kan overstyre metodene for JSONModel og tilpasse deres oppførsel, men du vil.

Åpen TagModel.m og overstyr standardbeskrivelsesmetoden:

- (NSString *) beskrivelse return self.tag; 

Når du nå ringer componentsJoinedBySeparator: på arrayet av koder, i stedet for standardbeskrivelsen for TagModel Du vil bare få taggen som ren tekst.

Prøv det ved å kjøre programmet enda en gang. Du bør nå se listen over koder som vises pent under hver spøk.

Konklusjon

Du har nå en grunnleggende forståelse av JSONModel biblioteket. Så langt har du lært:

  • hvordan lage en enkel modellklasse som arver fra JSONModel
  • hvordan du definerer nødvendige og valgfrie egenskaper
  • og hvordan man skal bygge modellerklasser

I denne korte opplæringen berørte jeg bare noen få av funksjonene i JSONModel bibliotek. I de neste delene av denne serien vil du lære mer om datatransformasjon, jobbe med eksterne JSON APIer, og du vil se på noen mer avanserte JSONModel-funksjoner.