objective c - NSURLSessionDataTask not called after NSURLSessionDownloadTask in the same NSURLSession in iOS background -


my ios app works in following way

  1. i have array of audio file names, check whether file present. if it's present starts playing it. once finished start playing next audio.

  2. if file not present make nsurlsessiondatatask post request returns me string url of file downloaded.(this url valid 1 minute).

  3. once receive url, make nsurlsessiondownloadtask request , download file, save file , play audio.

this entire process works fine when app in foreground. works fine when audios present , app running in background.

the problem comes when audio files not present , app running in background

my code : backgroundfetchmanager.h

@interface backgroundfetchmanager : nsobject <nsurlsessiondownloaddelegate,nsurlsessiondatadelegate>  @property bool isdownloading; @property nsurlsessiondownloadtask *download; @property nsurlsessiondatatask *datadownload; @property (nonatomic, strong)nsurlsession *backgroundsession; @property nsmutablearray *downloadqueue; @property fileaccessmanager *fileaccessmanager;  @end 

backgroundfetchmanager.m

initialization function

-(id) init {     self = [super init];     nsurlsessionconfiguration *config = [nsurlsessionconfiguration backgroundsessionconfigurationwithidentifier:@"testconfiguration"];     config.sessionsendslaunchevents = yes;     config.discretionary = yes;     self.backgroundsession = [nsurlsession sessionwithconfiguration:config delegate:self delegatequeue:[nsoperationqueue mainqueue]];     download = [nsurlsessiondownloadtask new];     datadownload = [nsurlsessiondatatask new];     return self; }  

data task

datadownload = [self.backgroundsession datataskwithrequest:request]; [datadownload settaskdescription:@"data task"]; 

delegates of datadownload (nsurlsessiondatatask)

- (void)urlsession:(nsurlsession *)session datatask:(nsurlsessiondatatask *)datatask didreceiveresponse:(nsurlresponse *)response  completionhandler:(void (^)(nsurlsessionresponsedisposition disposition))completionhandler {      completionhandler(nsurlsessionresponseallow); }  - (void)urlsession:(nsurlsession *)session datatask:(nsurlsessiondatatask *)datatask     didreceivedata:(nsdata *)data {     nsstring * str = [[nsstring alloc] initwithdata:data encoding:nsutf8stringencoding];     nsstring *url = [[nsstring alloc] initwithdata:data encoding:nsutf8stringencoding];     nslog(@"this response received %@",url);  //download nsurlsessiondownloadtask     download = [self.backgroundsession downloadtaskwithurl:[nsurl urlwithstring:url]];     [download resume];  } 

delegates of download (nsurlsessiondownloadtask)

these ones not called when app in background

- (void)urlsession:(nsurlsession *)session downloadtask:(nsurlsessiondownloadtask *)downloadtask didfinishdownloadingtourl:(nsurl *)location {     appdelegate *a = (appdelegate *)[[uiapplication sharedapplication] delegate];     nsurl *destinationurl = [fileaccessmanager savefile:a.downloadqueue[0] fromlocation:location]; // save file code }   - (void)urlsession:(nsurlsession *)session task:(nsurlsessiontask *)task didcompletewitherror:(nserror *)error {     // audio playing stuff      if (![task.taskdescription isequaltostring:@"data task"]) {         nslog(@"this did complete error %@", task );         appdelegate *a = (appdelegate *)[[uiapplication sharedapplication] delegate];         if ([a.downloadqueue[0] isequaltostring:a.audiotobeplayed]) {             nsdictionary* userinfo = @{@"file": a.downloadqueue[0]};             [[nsnotificationcenter defaultcenter] postnotificationname:@"playthisstuff" object:nil userinfo:userinfo];           } //starts next download         [a pop];         isdownloading = false;         if ([a.downloadqueue count] > 0) {             isdownloading = true;             [self downloadfile:a.downloadqueue[0]];         }     }         } 

so in nutshell, downloadtask not called after datatask has finished. as know, nsurlsession when configured backgroundsession, os takes responsiblity of download, ideally should work. missing ?

the problem stems fact ios won't let start new task while app in background. believe done prevent apps continuously firing off new tasks , keeping app alive indefinitely.

background tasks suitable gracefully handling app transitioning foreground background while task in progress. it's reason you're seeing first task complete, not second.

one workaround request background execution time os when fire off initial data task:

uibackgroundtaskidentifier backgroundtaskid = [[uiapplication sharedapplication] beginbackgroundtaskwithexpirationhandler:^{  }]; 

that should @ least give app few minutes of background time initiate second task. sure call -endbackgroundtask: after call -resume on second task.

unfortunately, cannot guarantee of files download. if find you're running out of background time, may better off using silent push notifications wake app , download periodically.


Comments

Popular posts from this blog

Command prompt result in label. Python 2.7 -

javascript - How do I use URL parameters to change link href on page? -

amazon web services - AWS Route53 Trying To Get Site To Resolve To www -