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.
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.
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.
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.
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.
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.
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:
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.
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;
TagModel
er protokollen du erklærte for et øyeblikk siden. Det forteller JokeModel
at arrayet av koder skal inneholde forekomster av TagModel
klasse.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.
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å skjermenvitser
å 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.
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?
[JokeModel arrayOfModelsFromData: error:]
tar JSON-dataene og gjør det til en rekke JSON-objekter.JokeModel
løkker over disse objektene og skaper JokeModel
forekomster fra hvert JSON-objekt.JokeModel
instans inspiserer JSON-dataene den mottar, og initierer sine egenskaper med de riktige verdiene.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];);
- (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.
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.
Du har nå en grunnleggende forståelse av JSONModel biblioteket. Så langt har du lært:
JSONModel
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.