før iOS 7 var utviklere ganske begrenset i hva de kunne gjøre når appene deres forlot forgrunnen. Bortsett FRA VOIP og stedsbaserte funksjoner, var den eneste måten å utføre kode i bakgrunnen å bruke bakgrunnsoppgaver, begrenset til å kjøre i noen minutter. Hvis du vil laste ned en stor video for frakoblet visning, eller sikkerhetskopiere brukerens bilder til serveren din, kan du bare fullføre en del av arbeidet.
iOS 7 legger til to Nye Api-Er for oppdatering av APPENS BRUKERGRENSESNITT og innhold i bakgrunnen. Den første, Bakgrunn Hente, lar deg hente nytt innhold fra nettverket med jevne mellomrom. Den Andre, Eksterne Varsler, er En ny funksjon som utnytter Push-Varsler for å varsle en app når en hendelse har skjedd. Begge disse nye mekanismene hjelper deg med å holde appens grensesnitt oppdatert, og kan planlegge arbeid på den nye Bakgrunnsoverføringstjenesten, som lar deg utføre nettverksoverføringer utenfor prosessen (nedlastinger og opplastinger).
Bakgrunn Hente Og Eksterne Varslinger er enkle program delegat kroker med 30 sekunder av vegg-klokke tid til å utføre arbeid før app er suspendert. De er ikke ment FOR CPU-intensivt arbeid eller lange løpende oppgaver, men de er for å kjøre opp langvarige nettverksforespørsler, som en stor filmnedlasting, eller utføre raske innholdsoppdateringer.
fra en brukers perspektiv er den eneste åpenbare endringen i multitasking den nye app switcher, som viser et øyeblikksbilde av hver apps BRUKERGRENSESNITT som det var da det forlot forgrunnen. Men det er en grunn til å vise øyeblikksbildene – du kan nå oppdatere appens øyeblikksbilde etter at du har fullført bakgrunnsarbeid, og viser en forhåndsvisning av nytt innhold. Sosiale nettverk, nyheter eller vær-apper kan nå vise det nyeste innholdet uten at brukeren må åpne appen. Vi ser hvordan du oppdaterer stillbildet senere.
Bakgrunn Hente
Bakgrunn Hente er en slags smart polling mekanisme som fungerer best for programmer som har hyppige innholdsoppdateringer, som sosiale nettverk, nyheter, eller vær apps. Systemet vekker appen basert på brukerens oppførsel, og tar sikte på å utløse bakgrunnshenting før brukeren starter appen. For eksempel, hvis brukeren alltid bruker en app på 1 pm, systemet lærer og tilpasser, utføre henter før bruk perioder. Bakgrunnshentinger samles på tvers av apper av enhetens radio for å redusere batteribruk, og hvis du rapporterer at nye data ikke var tilgjengelige under en henting, kan iOS tilpasse seg, ved hjelp av denne informasjonen for å unngå henting i rolige tider.
det første trinnet i å aktivere Bakgrunn Hente er å angi at du vil bruke funksjonen i UIBackgroundModes
– tasten i info plist. Den enkleste måten å gjøre dette på er å bruke den nye Evner-fanen I xcode 5s prosjektredigerer, som inkluderer En Bakgrunnsmodi-seksjon for enkel konfigurasjon av multitasking-alternativer.
Alternativt kan du redigere nøkkelen manuelt:
<key>UIBackgroundModes</key><array> <string>fetch</string></array>
neste, fortelle iOS hvor ofte du ønsker å hente:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ ; return YES;}
standard henteintervallet er aldri, så du må angi et tidsintervall, eller appen vil aldri bli kalt i bakgrunnen. Verdien på UIApplicationBackgroundFetchIntervalMinimum
ber systemet om å administrere når appen din er våknet, så ofte som mulig, men du bør angi ditt eget tidsintervall hvis dette er unødvendig. En vær-app kan for eksempel bare oppdatere betingelsene hver time. iOS vil vente minst det angitte tidsintervallet mellom bakgrunnshentinger.
hvis programmet tillater en bruker å logge ut, og du vet at det ikke vil være noen nye data, kan du angi minimumBackgroundFetchInterval
tilbake til UIApplicationBackgroundFetchIntervalNever
å være en god borger og å spare ressurser.
det siste trinnet er å implementere følgende metode i søknadsrepresentanten:
- (void) application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{ NSURLSessionConfiguration *sessionConfiguration = ; NSURLSession *session = ; NSURL *url = initWithString:@"http://yourserver.com/data.json"]; NSURLSessionDataTask *task = ; // Start the task ;}
det er her du kan utføre arbeid når du blir vekket av systemet. Husk at du bare har 30 sekunder på deg til å avgjøre om nytt innhold er tilgjengelig, behandle det nye innholdet og oppdatere BRUKERGRENSESNITTET. Dette bør være nok tid til å hente data fra nettverket og hente noen miniatyrbilder for BRUKERGRENSESNITTET ditt, men ikke mye mer. Når nettverksforespørslene er fullført og BRUKERGRENSESNITTET ditt er oppdatert, bør du ringe fullføringsbehandleren.
fullføringsbehandleren tjener to formål. Først måler systemet kraften som brukes av prosessen, og registrerer om nye data var tilgjengelige basert på argumentet UIBackgroundFetchResult
du passerte. For det andre, når du ringer fullføringsbehandleren, tas et øyeblikksbilde av BRUKERGRENSESNITTET, og appbryteren oppdateres. Brukeren vil se det nye innholdet når han eller hun bytter apps. Snapshotting-virkemåten er vanlig for alle fullføringsbehandlerne i de nye multitasking-Api-Ene.
i en real-world søknad, bør du sende completionHandler
til sub-komponenter i programmet og kaller det når du har behandlet data og oppdatert UI.
på dette tidspunktet lurer du kanskje på hvordan iOS kan snapshot appens BRUKERGRENSESNITT når den kjører i bakgrunnen, og hvordan applikasjonens livssyklus fungerer med Bakgrunnshenting. Hvis appen din er suspendert, vil systemet vekke den før du ringer application: performFetchWithCompletionHandler:
. Hvis appen din ikke kjører, starter systemet det, kaller de vanlige delegeringsmetodene, inkludert application: didFinishLaunchingWithOptions:
. Du kan tenke på det som app kjører akkurat på samme måte som om brukeren hadde lansert den Fra Springboard, bortsett FRA UI er usynlig, gjengitt offscreen.
i de fleste tilfeller vil du utføre det samme arbeidet når programmet starter i bakgrunnen som du ville gjort i forgrunnen, men du kan oppdage bakgrunnsstart ved å se på egenskapen applicationState
for UIApplication:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ NSLog(@"Launched in background %d", UIApplicationStateBackground == application.applicationState); return YES;}
Testing Bakgrunn Hente
det er to måter du kan simulere en bakgrunn hente. Den enkleste metoden er å kjøre programmet Fra Xcode og klikk Simulere Bakgrunn Hente Under Xcode Debug menyen mens programmet kjører.
Alternativt kan Du bruke et skjema til å endre Hvordan Xcode kjører appen din. Velg Skjema Under Menyelementet Xcode, Og Deretter Administrer Ordninger. Herfra kan du redigere eller legge til en ny ordning og sjekke Lanseringen på grunn av en bakgrunn hente hendelsen boksen som vist nedenfor.
Fjernvarslinger
Fjernvarslinger lar deg varsle appen din når viktige hendelser oppstår. Du kan ha nye direktemeldinger å levere, breaking news varsler å sende, eller den siste episoden av brukerens favoritt TV-show klar for ham eller henne til å laste ned for frakoblet visning. Fjernvarslinger er gode for sporadisk, men umiddelbart viktig innhold, der forsinkelsen mellom bakgrunnshentinger kanskje ikke er akseptabel. Eksterne Varsler kan også være mye mer effektiv Enn Bakgrunn Hente, som programmet starter bare når det er nødvendig.
En Ekstern Melding er egentlig bare en vanlig Push-Melding med flagget content-available
. Du kan sende en push med en varselmelding som informerer brukeren om at noe har skjedd, mens du oppdaterer BRUKERGRENSESNITTET i bakgrunnen. Men Eksterne Varsler kan også være stille, inneholder ingen varselmelding eller lyd, brukes bare til å oppdatere appens grensesnitt eller utløse bakgrunnsarbeid. Du kan da legge ut et lokalt varsel når du er ferdig med å laste ned eller behandle det nye innholdet.
Stille push-varslinger er rate-begrenset, så ikke vær redd for å sende så mange som søknaden din trenger. iOS og APNS-serverne vil kontrollere hvor ofte de leveres, og du kommer ikke i trøbbel for å sende for mange. Hvis push-varslingene dine er begrenset, kan de bli forsinket til neste gang enheten sender en keep-alive-pakke eller mottar et annet varsel.
Sende Eksterne Varsler
hvis du vil sende et eksternt varsel, angir du innholdsflagget i en nyttelast for push-varsling. Det innholdstilgjengelige flagget er den samme nøkkelen som brukes til å varsle Aviskiosk-apper, så de fleste push-skript og biblioteker støtter allerede eksterne varsler. Når du sender Et Eksternt Varsel, vil du kanskje også inkludere noen data i varselens nyttelast, slik at programmet kan referere til hendelsen. Dette kan spare deg for noen nettverksforespørsler og øke responsen til appen din.
jeg anbefaler At Du bruker Nomad CLI ‘ S Houston-verktøy for å sende push-meldinger mens du utvikler, men du kan bruke favorittbiblioteket eller skriptet ditt.
Du kan installere Houston som en del av nomad – cli ruby perle:
gem install nomad-cli
og send deretter et varsel med apn-verktøyet som er inkludert I Nomad
# Send a Push Notification to your Deviceapn push <device token> -c /path/to/key-cert.pem -n -d content-id=42
her angir flagget -n
at innholdsnøkkelen skal inkluderes, og -d
lar oss legge til egne datanøkler i nyttelasten.
den resulterende varslings nyttelast ser slik ut:
{ "aps" : { "content-available" : 1 }, "content-id" : 42}
iOS 7 legger til en ny applikasjonsdelegatmetode, som kalles når et push-varsel med innholdstilgjengelig nøkkel mottas:
- (void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{ NSLog(@"Remote Notification userInfo is %@", userInfo); NSNumber *contentID = userInfo; // Do something with the content ID completionHandler(UIBackgroundFetchResultNewData);}
igjen blir appen lansert i bakgrunnen og gitt 30 sekunder for å hente nytt innhold og oppdatere BRUKERGRENSESNITTET, før du ringer fullføringsbehandleren. Vi kunne utføre en rask nettverksforespørsel som vi gjorde i Bakgrunnen Hente eksempel, men la oss bruke den kraftige Nye Bakgrunn Transfer Service til enqueue en stor nedlasting oppgave og se hvordan vi kan oppdatere VÅR UI når den er ferdig.
Nsurlsession Og Bakgrunn Transfer Service
mens NSURLSession
er en ny klasse i iOS 7, det refererer også til den nye teknologien I Foundation nettverk. Ment å erstatte NSURLConnection
, er kjente begreper og klasser som NSURL
, NSURLRequest
og NSURLResponse
bevart. Du vil jobbe med NSURLConnection
‘s erstatning, NSURLSessionTask
, for å gjøre nettverksforespørsler og håndtere svarene deres. Det er tre typer øktoppgaver-data, nedlasting og opplasting-som hver legger til syntaktisk sukker til NSURLSessionTask
, så du bør bruke den riktige for din brukstilfelle.
En NSURLSession
koordinerer en eller flere av disse NSURLSessionTask
s og oppfører seg i henhold til NSURLSessionConfiguration
som den ble opprettet med. Du kan opprette flere NSURLSession
s for å gruppere relaterte oppgaver med samme konfigurasjon. For å samhandle med Bakgrunnsoverføringstjenesten oppretter du en øktkonfigurasjon med . Oppgaver som legges til i en bakgrunnsøkt, kjøres i en ekstern prosess og fortsetter selv om appen din er suspendert, krasjer eller blir drept.
NSURLSessionConfiguration
lar deg angi STANDARD HTTP-overskrifter, konfigurere hurtigbufferpolicyer, begrense bruken av mobilnettverket med mer. Ett alternativ er flagget discretionary
, som gjør at systemet kan planlegge oppgaver for optimal ytelse. Hva dette betyr er at overføringene dine bare går Over Wifi når enheten har tilstrekkelig strøm. Hvis batteriet er lavt, eller bare en mobilforbindelse er tilgjengelig, kjører ikke oppgaven. Flagget discretionary
har bare effekt hvis øktkonfigurasjonsobjektet er konstruert ved å ringe til metoden backgroundSessionConfiguration:
, og hvis bakgrunnsoverføringen startes mens appen er i forgrunnen. Hvis overføringen startes fra bakgrunnen, vil overføringen alltid kjøre i skjønnsmessig modus.
Nå vet vi litt om NSURLSession
, og hvordan en bakgrunnsøkt fungerer, la oss gå tilbake til Vårt Eksterne Varslingseksempel og legge til litt kode for å enqueue en nedlasting på bakgrunnsoverføringstjenesten. Når nedlastingen er fullført, varsler vi brukeren om at filen er tilgjengelig for bruk.
NSURLSessionDownloadTask
Først av Alt, la oss håndtere Et Eksternt Varsel og enqueue en NSURLSessionDownloadTask
på bakgrunnsoverføringstjenesten. I backgroundURLSession
oppretter vi en NURLSession
med en bakgrunnsøktkonfigurasjon og legger til vår applikasjonsdelegat som øktdelegat. Dokumentasjonen fraråder å starte flere økter med samme identifikator, så vi bruker dispatch_once
for å unngå potensielle problemer:
- (NSURLSession *)backgroundURLSession{ static NSURLSession *session = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSString *identifier = @"io.objc.backgroundTransferExample"; NSURLSessionConfiguration* sessionConfig = ; session = ]; }); return session;}- (void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{ NSLog(@"Received remote notification with userInfo %@", userInfo); NSNumber *contentID = userInfo; NSString *downloadURLString = ]; NSURL* downloadURL = ; NSURLRequest *request = ; NSURLSessionDownloadTask *task = downloadTaskWithRequest:request]; task.taskDescription = ]; ; completionHandler(UIBackgroundFetchResultNewData);}
vi lager en nedlastingsoppgave ved hjelp av klassemetoden NSURLSession
og konfigurerer forespørselen, og gir en beskrivelse for bruk senere. Du må huske å ringe for å faktisk starte aktiviteten, da alle øktoppgaver begynner i suspendert tilstand.
nå må Vi implementere NSURLSessionDownloadDelegate
metoder for å motta tilbakeringinger når nedlastingen er fullført. Du må kanskje også implementere NSURLSessionDelegate
– eller NSURLSessionTaskDelegate
– metoder hvis du må håndtere godkjenning eller andre hendelser i øktens livssyklus. Du bør konsultere Apples dokumentlivssyklus for EN URL-Økt med Tilpassede Representanter, som forklarer hele livssyklusen på tvers av alle typer øktoppgaver.
ingen av NSURLSessionDownloadDelegate
delegeringsmetodene er valgfrie, men den eneste der vi må handle i dette eksemplet er . Når oppgaven er ferdig lastet ned, får du en midlertidig URL til filen på disken. Du må flytte eller kopiere filen til appens lagring, da den vil bli fjernet fra midlertidig lagring når du kommer tilbake fra denne delegeringsmetoden.
#Pragma Mark - NSURLSessionDownloadDelegate- (void) URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{ NSLog(@"downloadTask:%@ didFinishDownloadingToURL:%@", downloadTask.taskDescription, location); // Copy file to your app's storage with NSFileManager // ... // Notify your UI}- (void) URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes{}- (void) URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{}
hvis appen din fortsatt kjører i forgrunnen når bakgrunnsøktoppgaven er fullført, vil koden ovenfor være tilstrekkelig. I de fleste tilfeller vil appen din imidlertid ikke kjøre, eller den vil bli suspendert i bakgrunnen. I disse tilfellene må du implementere to programdelegatemetoder slik at systemet kan vekke programmet. I motsetning til tidligere representantanrop, kalles programrepresentanten to ganger, da økt-og aktivitetsrepresentantene kan motta flere meldinger. App delegate-metoden application: handleEventsForBackgroundURLSession:
kalles før disse NSURLSession
delegate-meldingene sendes, og URLSessionDidFinishEventsForBackgroundURLSession
kalles etterpå. I den tidligere metoden lagrer du en bakgrunn completionHandler
, og i sistnevnte kaller du det for å oppdatere BRUKERGRENSESNITTET:
- (void) application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler{ // You must re-establish a reference to the background session, // or NSURLSessionDownloadDelegate and NSURLSessionDelegate methods will not be called // as no delegate is attached to the session. See backgroundURLSession above. NSURLSession *backgroundSession = ; NSLog(@"Rejoining session with identifier %@ %@", identifier, backgroundSession); // Store the completion handler to update your UI after processing session events ;}- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session{ NSLog(@"Background URL session %@ finished events.\n", session); if (session.configuration.identifier) { // Call the handler we stored in -application:handleEventsForBackgroundURLSession: ; }}- (void)addCompletionHandler:(CompletionHandlerType)handler forSession:(NSString *)identifier{ if () { NSLog(@"Error: Got multiple handlers for a single session identifier. This should not happen.\n"); } ;}- (void)callCompletionHandlerForSession: (NSString *)identifier{ CompletionHandlerType handler = ; if (handler) { ; NSLog(@"Calling completion handler for session %@", identifier); handler(); }}
denne to-trinns prosessen er nødvendig for å oppdatere appgrensesnittet hvis du ikke allerede er i forgrunnen når bakgrunnsoverføringen er fullført. I tillegg, hvis appen ikke kjører i det hele tatt når bakgrunnsoverføringen er ferdig, vil iOS starte den i bakgrunnen, og de foregående applikasjons-og øktdelegatmetodene kalles etter application:didFinishLaunchingWithOptions:
.
Konfigurasjon Og Begrensning
vi har kort berørt kraften til bakgrunnsoverføringer, Men du bør utforske dokumentasjonen og se på alternativene NSURLSessionConfiguration
som best støtter brukstilfellet ditt. For eksempel NSURLSessionTasks
støtte ressurs tidsavbrudd gjennom egenskapen NSURLSessionConfiguration
timeoutIntervalForResource
. Du kan bruke dette til å angi hvor lenge du vil tillate en overføring å fullføre før du gir opp helt. Du kan bruke dette hvis innholdet ditt bare er tilgjengelig i en begrenset periode, eller hvis du ikke laster ned eller laster opp ressursen innen den gitte timeInterval, indikerer at brukeren ikke har tilstrekkelig Wifi-båndbredde.
i tillegg til å laste ned oppgaver, støtter NSURLSession
fullt opplastingsoppgaver, slik at du kan laste opp en video til serveren din i bakgrunnen og forsikre brukeren om at han eller hun ikke lenger trenger å forlate appen som kjører, som det kan ha blitt gjort i iOS 6. En fin touch ville være å sette sessionSendsLaunchEvents
egenskapen til NSURLSessionConfiguration
til NO
, hvis appen din ikke trenger å starte i bakgrunnen når overføringen er fullført. Effektiv bruk av systemressurser holder både iOS og brukeren fornøyd.
Til Slutt er Det et par begrensninger i bruk av bakgrunnsøkter. Som en representant kreves, kan du ikke bruke de enkle blokkbaserte tilbakeringingsmetodene på NSURLSession
. Starte din app i bakgrunnen er relativt dyrt, SÅ HTTP viderekoblinger er alltid tatt. Bakgrunnsoverføringstjenesten støtter BARE HTTP og HTTPS, og du kan ikke bruke egendefinerte protokoller. Systemet optimaliserer overføringer basert på tilgjengelige ressurser, og du kan ikke tvinge overføringen til fremgang i bakgrunnen til enhver tid.
vær Også oppmerksom på at NSURLSessionDataTasks
ikke støttes i bakgrunnsøkter i det hele tatt, og du bør bare bruke disse oppgavene for kortvarige, små forespørsler, ikke for nedlastinger eller opplastinger.
Sammendrag
de kraftige nye api-Ene for multitasking og nettverk i iOS 7 åpner for en rekke muligheter for både nye og eksisterende apper. Vurder brukstilfellene i appen din, som kan dra nytte av nettverksoverføringer utenfor prosess og ferske data, og få mest mulig ut av disse fantastiske Nye Api-Ene. Generelt implementerer bakgrunnsoverføringer som om programmet kjører i forgrunnen, gjør passende UI-oppdateringer, og det meste av arbeidet er allerede gjort for deg.
-
Bruk riktig NY API for appens innhold.
-
Være effektiv, og ringe ferdigstillelse handlers så tidlig som mulig.
-
Fullføringsbehandlere oppdaterer appens UI-øyeblikksbilde.
Videre Lesing
-
WWDC 2013 session «Hva Er Nytt Med Multitasking»
-
WWDC 2013 session «Hva Er Nytt I Foundation Networking»
-
URL Laster Systemprogrammeringsveiledning