Nettverk med NSURLSession Del 1

Fra en utviklerperspektiv er en av de mest signifikante endringene i iOS 7 og OS X Mavericks for det saks skyld introduksjonen av NSURLSession. Selv om NSURLSession kan virke skremmende ved første øyekast, det er viktig at du forstår hva det er, hvordan det gjelder NSURLConnection, og hva forskjellene er. I denne serien tar jeg deg gjennom grunnleggende NSURLSession slik at du kan dra nytte av denne nye teknologien i dine egne applikasjoner.


Hvorfor erstatte NSURLConnection?

Det første spørsmålet du kan spørre deg selv er hvorfor Apple fant det nødvendig å introdusere NSURLSession mens vi er helt fornøyd med NSURLConnection. Det virkelige spørsmålet er om du er trives med NSURLConnection. Husker du den tiden du forbannet og kastet ting på NSURLConnection? De fleste kakaoutviklere har vært på det stedet, og derfor bestemte Apple seg for å gå tilbake til tegnebrettet og skape en mer elegant løsning, bedre egnet for den moderne web.

Selv om NSURLSession og NSURLConnection har mye til felles når det gjelder hvordan de jobber, på et grunnleggende nivå, er de ganske forskjellige. Apple opprettet NSURLSession å ligne de generelle konseptene til NSURLConnection, men du vil lære i løpet av denne serien at NSURLSession er moderne, enklere å bruke, og bygget med mobil i tankene.


Hva er NSURLSession?

Før jeg diskuterer forskjellene mellom NSURLSession og NSURLConnection, det er en god ide å først se nærmere på hva NSURLSession er. Til tross for navnet sitt, NSURLSession er ikke bare en annen klasse du kan bruke i en iOS- eller OS X-applikasjon. NSURLSession er først og fremst en teknologi akkurat som NSURLConnection er.

Økter er containere

NSURLSession og NSURLConnection Begge gir en API for å samhandle med ulike protokoller, for eksempel HTTP og HTTPS. Sessionsobjektet, en forekomst av NSURLSession klassen, er det som forvalter denne interaksjonen. Det er en svært konfigurerbar beholder med en elegant API som gir mulighet for finkornet kontroll. Det tilbyr funksjoner som er fraværende i NSURLConnection. Hva mer med NSURLSession, Du kan utføre oppgaver som ikke er mulig med NSURLConnection, for eksempel implementering av privat surfing.

oppgaver

Den grunnleggende arbeidsenheten når du arbeider med NSURLSession er oppgaven, en forekomst av NSURLSessionTask. Det er tre typer oppgaver, dataoppgaver, laste opp oppgaver, og nedlastingsoppgaver.

  • Du bruker oftest dataoppgaver, som er forekomster av NSURLSessionDataTask. Dataoppgaver brukes til å be om data fra en server, for eksempel JSON-data. Hovedforskjellen med opplastings- og nedlastingsoppgaver er at de returnerer data direkte til søknaden din i stedet for å gå gjennom filsystemet. Dataene lagres bare i minnet.
  • Som navnet antyder, lastes opplastingsoppgaver for å laste opp data til et fjernt reisemål. De NSURLSessionUploadTask er en underklasse av NSURLSessionDataTask og oppfører seg på lignende måte. En av de viktigste forskjellene med en vanlig dataoppgave er at opplastingsoppgaver kan brukes i en økt som er opprettet med en bakgrunnssesjonskonfigurasjon.
  • Last ned oppgaver, forekomster av NSURLSessionDownloadTask, arve direkte fra NSURLSessionTask. Den viktigste forskjellen med dataoppgaver er at en nedlastingsoppgave skriver sitt svar direkte til en midlertidig fil. Dette er ganske forskjellig fra en vanlig dataoppgave som lagrer svaret i minnet. Det er mulig å Avbryt en nedlastingsoppgave og gjenoppta det på et senere tidspunkt.

Som du kan forestille deg, er asynkronicitet et nøkkelbegrep i NSURLSession. De NSURLSession API returnerer data ved å påkalle en sluttbehandler eller gjennom øktens delegat. API av NSURLSession ble designet med fleksibilitet i tankene som du vil legge merke til litt senere i denne opplæringen.

Møt familien

Som jeg nevnte tidligere, NSURLSession er både en teknologi og en klasse som du skal jobbe med. De NSURLSession API huser en rekke klasser, men NSURLSession er nøkkelkomponenten som sender forespørsler og mottar svar. Konfigurasjonen av sesjonsobjektet håndteres imidlertid av en forekomst av NSURLSessionConfiguration klasse. De NSURLSessionTask klassen og de tre konkrete underklassene er arbeiderne og brukes alltid i forbindelse med en økt som det er økten som lager oppgavene.

Delegasjon

Både NSURLSession og NSURLConnection stole tungt på delegasjonsmønsteret. De NSURLSessionDelegate protokollen erklærer en håndfull delegerte metoder for å håndtere hendelser på øktnivå. i tillegg NSURLSessionTask Klasser og underklasser hver erklære en delegatprotokoll for å håndtere hendelsesnivåhendelser.

Gamle venner

De NSURLSession API bygger på klasser som du allerede er kjent med, for eksempel NSURL, NSURLRequest, og NSURLResponse.


Hva er forskjellene?

Hvordan gjør NSURLSession Er forskjellig fra NSURLConnection? Dette er et viktig spørsmål, fordi NSURLConnection blir ikke avskrevet av Apple. Du kan fortsatt bruke NSURLConnection i dine prosjekter. Hvorfor skal du bruke NSURLSession?

Det første å forstå er at NSURLSession eksempel er objektet som styrer forespørselen og svaret. Dette ligner på hvordan NSURLConnection fungerer, men hovedforskjellen er at konfigurasjonen av forespørselen håndteres av øktobjektet, som er et langt levet objekt. Dette gjøres gjennom NSURLSessionConfiguration klasse. Ikke bare gir den NSURLSession API finkornet konfigurasjon gjennom NSURLSessionConfiguration klassen, oppfordrer den adskillelsen av data (forespørsel) fra metadata. De NSURLSessionDownloadTask illustrerer dette bra ved å skrive svaret på filsystemet direkte.

Autentisering er enklere og håndteres mer elegant NSURLSession. De NSURLSession API håndterer autentisering på en tilkoblingsbasis i stedet for på forespørsel, som NSURLConnection gjør. De NSURLSession API gjør det også lettere å gi HTTP-alternativer, og hver økt kan ha en separat lagringsbeholder avhengig av hvordan du konfigurerer økten.

I introduksjonen fortalte jeg deg det NSURLSession gir et moderne grensesnitt, som integrerer grasiøst med iOS 7. Et eksempel på denne integrasjonen er NSURLSession's out-of-process opplastinger og nedlastinger. NSURLSession er optimalisert for å bevare batteriets levetid, støtter pauser, kansellering og gjenopptak av oppgaver, samt UIKits multitasking API. Hva er ikke å elske om NSURLSession?


Få føttene våte

Trinn 1: Prosjektoppsett

En ny API er best lært av praksis, så det er på tide å brann opp Xcode og få føttene våte. Start Xcode 5, opprett et nytt prosjekt ved å velge Nytt> Prosjekt ... fra Fil menyen, og velg Enkeltvisningsprogram mal fra listen over iOS-applikasjonsmaler.


Gi prosjektet ditt et navn, fortell Xcode hvor du vil lagre det, og klikk Skape. Det er ikke nødvendig å sette prosjektet under kildekontroll.


Trinn 2: Lag et sesjonsobjekt

Når du arbeider med NSURLSession, Det er viktig å forstå at øktobjektet, en forekomst av NSURLSession, er stjernespilleren. Den håndterer forespørsler og svar, konfigurerer forespørsler, styrer lagringsplass og stat, etc. Opprettelse av en økt kan gjøres på flere måter. Den raskeste måten å komme i gang er å bruke NSURLSession's sharedSession klassemetode som vist nedenfor.

 - (void) viewDidLoad [super viewDidLoad]; NSURLSession * session = [NSURLSession sharedSession]; 

Lage en økt objekt i visningsregulatorens viewDidLoad metode som vist ovenfor. De økt objekt vi opprettet er bra for vårt eksempel, men du vil sikkert ha litt mer fleksibilitet i de fleste tilfeller. De økt objekt vi nettopp har laget, bruker den globale NSURLCache, NSHTTPCookieStorage, og NSURLCredentialStorage. Dette betyr at det fungerer ganske lik en standard implementering av NSURLConnection.

Trinn 3: Lag en dataoppgave

Å sette økt protestere mot bruk, la oss spørre iTunes Store Search API og søke etter programvare laget av Apple. ITunes Store Search API er lett å bruke og krever ingen godkjenning, noe som gjør den ideell for eksempelet vårt.

For å spørre søkeprogrammet, må vi sende en forespørsel til https://itunes.apple.com/search og pass noen parametere. Som vi så tidligere, da vi brukte NSURLSession API, en forespørsel representeres av en oppgave. For å spørre søkeprogrammet, er alt vi trenger en datahandel, en forekomst av NSURLSessionDataTask klasse. Ta en titt på den oppdaterte viewDidLoad implementering vist nedenfor.

 - (void) viewDidLoad [super viewDidLoad]; NSURLSession * session = [NSURLSession sharedSession]; NSURLSessionDataTask * dataTask = [session dataTaskWithURL: [NSURL URLWithString: @ "https://itunes.apple.com/search?term=apple&media=software"] completionHandler: ^ (NSData * data, NSURLResponse * respons, NSError * feil)  NSDictionary * json = [NSJSONSerialization JSONObjectWithData: dataalternativer: 0 feil: null]; NSLog (@ "% @", json); ]; 

Det finnes en rekke metoder tilgjengelig for å opprette en oppgave, men nøkkelbegrepet å forstå er at økt objekt gjør selve opprettelsen og konfigurasjonen av oppgaven. I dette eksemplet påberoper vi oss dataTaskWithURL: completionHandler: og gi det en forekomst av NSURL samt en ferdigstillingshåndterer. Fullføringsbehandleren aksepterer tre argumenter, den Rå data av svaret (NSData), den responsobjekt (NSURLResponse), og en feilobjekt (NSError). Hvis forespørselen er vellykket, er feilobjektet nil. Fordi vi vet at forespørselen returnerer et JSON-svar, oppretter vi en Fundament objekt fra data objekt som vi har mottatt og logg utgangen til konsollen.

Det er viktig å forstå at feil objektet som sendes til fullføringsbehandleren, er bare befolket, ikke nil, hvis forespørselen mislyktes eller det oppsto en feil. Med andre ord, hvis forespørselen returnerte a 404 svaret, ble forespørselen lykkes så langt som øktene angår. De feil objektet vil da være nil. Dette er et viktig konsept å forstå når du arbeider med NSURLSession og NSURLConnection for den saks skyld.

Bygg prosjektet og kjør programmet i iOS-simulatoren eller på en fysisk enhet, og inspiser Xcode's Console. Ingenting skrives ut på konsollen. Hva gikk galt? Som jeg tidligere nevnte, NSURLSession API støtter pauser, kansellering og gjenopptakelse av oppgaver eller forespørsler. Denne oppførselen ligner på NSOperation og det kan minne deg om AFNetworking-biblioteket. En oppgave har a stat Egenskap som angir om oppgaven er løping (NSURLSessionTaskStateRunning), suspendert (NSURLSessionTaskStateSuspended), avbryter (NSURLSessionTaskStateCanceling), eller fullført (NSURLSessionTaskStateCompleted). Når et øktobjekt oppretter en oppgave, starter oppgaven sitt liv i suspendert stat. For å starte oppgaven må vi fortelle det til gjenoppta ved å ringe gjenoppta på oppgaven. Oppdater viewDidLoad metode som vist nedenfor, kjør programmet en gang til, og inspiser utgangen i konsollen. Oppdrag utført.

 - (void) viewDidLoad [super viewDidLoad]; NSURLSession * session = [NSURLSession sharedSession]; NSURLSessionDataTask * dataTask = [session dataTaskWithURL: [NSURL URLWithString: @ "https://itunes.apple.com/search?term=apple&media=software"] completionHandler: ^ (NSData * data, NSURLResponse * respons, NSError * feil)  NSDictionary * json = [NSJSONSerialization JSONObjectWithData: dataalternativer: 0 feil: null]; NSLog (@ "% @", json); ]; [dataTask CV]; 

Laster ned en ekstern ressurs

I det forrige eksempelet benyttet vi en fullføringshåndterer til å behandle svaret vi mottok fra forespørselen. Det er også mulig å oppnå det samme resultatet ved å implementere oppgavegruppeprotokollen (e). La oss se hva som kreves for å laste ned et bilde ved å utnytte NSURLSession og NSURLSessionDownloadTask.

Trinn 1: Opprett brukergrensesnittet

Åpen MTViewController.h og opprett to utsalgssteder som vist nedenfor. Vi bruker det første utløpet, en forekomst av UIImageView, for å vise det nedlastede bildet til brukeren. Det andre utløpet, en forekomst av UIProgressView, vil vise fremdriften av nedlastingsoppgaven.

 #importere  @interface MTViewController: UIViewController @property (svak, ikkeatomisk) IBOutlet UIImageView * imageView; @property (svak, ikkeatomisk) IBOutlet UIProgressView * progressView; @slutt

Åpne prosjektets hovedhistorieplate (Main.storyboard), dra a UIImageView forekommer til visningskontrollørens visning, og koble utsignalkontrollens uttak som vi nettopp har opprettet i tittelkontrollens headerfil. Gjenta denne prosessen for fremdriftsvisningen.


Trinn 2: Opprett en nedlastingsoppgave

I dette eksemplet vil vi ikke gjøre bruk av sharedSession klassemetode, fordi vi må konfigurere økt objekt som vi vil bruke til å gjøre forespørselen. Oppdater implementeringen av viewDidLoad som vist under.

 - (void) viewDidLoad [super viewDidLoad]; NSURLSessionConfiguration * sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; NSURLSession * session = [NSURLSession sessionWithConfiguration: sessionConfiguration delegate: self delegateQueue: null]; NSURLSessionDownloadTask * downloadTask = [Session downloadTaskWithURL: [NSURL URLWithString: @ "http://cdn.tutsplus.com/mobile/uploads/2013/12/sample.jpg"]]; [downloadTask resume]; 

For å forhindre at en kompilervarsel kommer opp, må du sørge for at den samsvarer med MTViewController klasse til NSURLSessionDelegate og NSURLSessionDownloadDelegate protokoller som vist nedenfor.

 #import "MTViewController.h" @interface MTViewController ()  @slutt

I viewDidLoad, vi lager en forekomst av NSURLSessionConfiguration klasse ved å påkalle defaultSessionConfiguration klassemetode. Som nevnt i dokumentasjonen, oppfører sesjonen seg mye som en forekomst av NSURLConnection i standardkonfigurasjonen, som er bra for vårt eksempel.

I dette eksempelet oppretter vi en NSURLSession eksempel ved å påkalle sessionWithConfiguration: delegat: delegateQueue: klassemetode og passere sessionConfiguration objekt vi opprettet for et øyeblikk siden. Vi stiller visningscontrolleren som øktdelegate og passerer nil som det tredje argumentet. Du kan ignorere det tredje argumentet for nå. Hovedforskjellen med det forrige eksempelet er at vi setter økts delegert til visningskontrolløren.

For å laste ned bildet må vi opprette en nedlastingsoppgave. Vi gjør dette ved å ringe downloadTaskWithURL:økt objekt, passerer en forekomst av NSURL, og ringer gjenoppta på nedlastingsoppgaven. Vi kunne ha brukt en ferdigstillingshåndterer som vi gjorde tidligere, men jeg vil vise deg mulighetene til å bruke en delegat i stedet.

Trinn 3: Implementer den delegerte protokollen

For å gjøre alt dette arbeidet, må vi implementere de tre delegerte metodene til NSURLSessionDownloadDelegate protokollen, URLSession: downloadTask: didFinishDownloadingToURL:, URLSession: downloadTask: didResumeAtOffset: expectedTotalBytes:, og URLSession: downloadTask: downloadTask didWriteData: totalBytesWritten: totalBytesExpectedToWrite:. Gjennomføringen av hver metode er ganske enkelt. Det er viktig å merke seg at vi må oppdatere brukergrensesnittet på hovedtråden ved hjelp av GCD (Grand Central Dispatch). Ved å passere nil som det tredje argumentet til sessionWithConfiguration: delegat: delegateQueue:, operativsystemet opprettet en bakgrunnskø for oss. Dette er greit, men det betyr også at vi må være oppmerksomme på at delegatemetoder påberopes på en bakgrunnstråd i stedet for hovedtråden. Bygg prosjektet og kjør programmet for å se resultatet av vårt harde arbeid.

 - (void) URLSession: (NSURLSession *) sessionsnedlastningTask: (NSURLSessionDownloadTask *) downloadTask didFinishDownloadingToURL: (NSURL *) sted NSData * data = [NSData dataWithContentsOfURL: location]; dispatch_async (dispatch_get_main_queue (), ^ self.progressView setHidden: YES]; [self.imageView setImage: [UIImage imageWithData: data]];);  - (ugyldig) URLSession: (NSURLSession *) sessionsnedlastningTask: (NSURLSessionDownloadTask *) downloadTask didResumeAtOffset: (int64_t) fileOffset forventetTotalBytes: (int64_t) forventetTotalBytes  - (ugyldig) URLSession: (NSURLSession *) økt nedlastingTask: (NSURLSessionDownloadTask *) downloadTask didWriteData: (int64_t) bytesVerdet totaltBytesWritten: (int64_t) totalBytesBrevet totaltBytesExpectedToWrite: (int64_t) totalBytesExpectedToWrite float progress = (double) totalBytesWritten / (double) totalBytesExpectedToWrite; dispatch_async (dispatch_get_main_queue (), ^ [self.progressView setProgress: progress];); 

Konklusjon

Med disse to eksemplene bør du ha en grunnleggende forståelse av grunnleggende for NSURLSession API, hvordan det sammenlignes med NSURLConnection, og hva fordelene er det. I neste del av denne serien vil vi se på mer avanserte funksjoner av NSURLSession.