ios7 – iOS 7 NSURLSession在后台下载多个文件

ios7 – iOS 7 NSURLSession在后台下载多个文件,第1张

概述我想使用NSUrlSession下载文件列表. 我有一个用于计算成功下载的变量@property(nonatomic)int downloadsSuccessfulCounter;.在下载文件时,我禁用了下载按钮.当计数器等于下载列表大小时,我再次启用该按钮并将计数器设置为0.我在方法中执行此 *** 作: -(void)URLSession:(NSURLSession *)session downloa 我想使用NSUrlSession下载文件列表.

我有一个用于计算成功下载的变量@property(nonatomic)int downloadsSuccessfulCounter;.在下载文件时,我禁用了下载按钮.当计数器等于下载列表大小时,我再次启用该按钮并将计数器设置为0.我在方法中执行此 *** 作:

-(voID)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask dIDFinishDownloadingToURL:(NSURL *)location {...    [[NSOperationQueue mainQueue] addOperationWithBlock:^ {        downloadsSuccessfulCounter++;        if(downloadsSuccessfulCounter == self.downloadList.count) {            NSLog(@"All downloads finished");            [self.syncbutton setEnabled:YES];             downloadsSuccessfulCounter = 0;        }    }];

}

一切都运行正常,但是当我再次打开VIEwController时,我收到消息一个带有标识符com.myApp的后台URLSession已经存在!计数器未设置为0,UI元素(UIbuttons,UILabels)没有响应.

我想问题是因为NSURLSession仍然是开放的,但我不确定它是如何工作的.

我已经尝试了所有教程,但其中99%仅用于下载1个文件,不超过1个…
有任何想法吗?

这是我的代码:

...    @property (nonatomic,strong) NSURLSession *session;...    - (voID)vIEwDIDLoad {        [super vIEwDIDLoad];        appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];        self.downloadList = [[NSMutableArray alloc] init];        NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.myApp"];        sessionConfiguration.httpMaximumConnectionsPerHost = 5;        self.session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:nil];}

当我按下Download buttonI时调用此方法(
我有一个包含NSURLSessionDownloadTask的可下载对象:

-(voID)startDownload {    for (int i=0; i<[self.downloadList count]; i++) {        Downloadable *d = [self.downloadList objectAtIndex:i];        if (!d.isDownloading) {            if (d.taskIDentifIEr == -1) {                d.downloadTask = [self.session downloadTaskWithURL:[NSURL URLWithString:d.downloadSource]];            }else {                d.downloadTask = [self.session downloadTaskWithResumeData:fdi.taskResumeData];            }            d.taskIDentifIEr = d.downloadTask.taskIDentifIEr;            [d.downloadTask resume];            d.isDownloading = YES;        }    }}

当应用程序处于后台时:

-(voID)URLSessionDIDFinishEventsForBackgroundURLSession:(NSURLSession *)session{    AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;    [self.session getTasksWithCompletionHandler:^(NSArray *dataTasks,NSArray *uploadTasks,NSArray *downloadTasks) {        if ([downloadTasks count] == 0) {            if (appDelegate.backgroundTransferCompletionHandler != nil) {                voID(^completionHandler)() = appDelegate.backgroundTransferCompletionHandler;                appDelegate.backgroundTransferCompletionHandler = nil;                [[NSOperationQueue mainQueue] addOperationWithBlock:^{                                   completionHandler();                    UIlocalnotification *localnotification = [[UIlocalnotification alloc] init];                    localnotification.alertbody = @"All files downloaded";                    [[UIApplication sharedApplication] presentlocalnotificationNow:localnotification];                }];            }        }    }];}
解决方法 因此,正如我在评论中提到的,问题是每个文件都需要一个唯一的NSURLSession,并且每个NSURLSession都需要一个具有唯一标识符的NSURLSessionConfiguration.

我认为你很亲密 – 在某些方面可能比我更合适……
您只需要创建一个结构,将唯一ID传递给唯一的配置,以填充唯一的会话(比如快10倍).

这是我做的:

/ *
*检索要下载的文件列表
*还使用该列表的大小来实例化项目
*在我的情况下,我加载一个字符返回的文本文件,其中包含我要下载的文件的名称
* /

- (voID) getMediaList {    Nsstring *List = @"http://myserver/media_List.txt";    NSURLSession *session = [NSURLSession sharedSession]; // <-- BASIC session    [[session dataTaskWithURL:[NSURL URLWithString:List]            completionHandler:^(NSData *data,NSURLResponse *response,NSError *error) {                Nsstring *stringFromData = [[Nsstring alloc] initWithData: data enCoding: NSUTF8StringEnCoding];                // Populate Arrays                REMOTE_MEDIA_file_PATHS = [stringFromData componentsSeparatedByString:@"\n"];                [self instantiateURLSessions:[REMOTE_MEDIA_file_PATHS count]];                 // Start First file                [self getfile:[REMOTE_MEDIA_file_PATHS objectAtIndex:downloadCounter]:downloadCounter]; // this variable is 0 at the start            }]     resume];}

/ *
*这将配置和会话数组设置为适当的大小
*它还为每个人提供唯一的ID
* /

- (voID) instantiateURLSessions : (int) size {    NSMutableArray *configurations = [NSMutableArray array];    NSMutableArray *sessions = [NSMutableArray array];    for (int i = 0; i < size; i++) {        Nsstring *index = [Nsstring stringWithFormat:@"%i",i];        Nsstring *UniqueIDentifIEr = @"MyAppBackgroundSessionIDentifIEr_";        UniqueIDentifIEr = [UniqueIDentifIEr stringByAppendingString:index];        [configurations addobject: [NSURLSessionConfiguration backgroundSessionConfigurationWithIDentifIEr:UniqueIDentifIEr]];        [sessions addobject:[NSURLSession sessionWithConfiguration: [configurations objectAtIndex:i]  delegate: self delegateQueue: [NSOperationQueue mainQueue]]];    }    NSURL_BACKGROUND_CONfigURATIONS = [NSArray arrayWithArray:configurations];    NSURL_BACKGROUND_SESSIONS = [NSArray arrayWithArray:sessions];}

/ *
*这将根据数组的索引为每个文件设置下载任务
*它还连接到实际文件的路径
* /

- (voID) getfile : (Nsstring*) file :(int) index {    Nsstring *fullPathTofile = REMOTE_MEDIA_PATH; // Path To Server With files    fullPathTofile = [fullPathTofile stringByAppendingString:file];    NSURL *url = [NSURL URLWithString:fullPathTofile];    NSURLSessionDownloadTask *downloadTask = [[NSURL_BACKGROUND_SESSIONS objectAtIndex:index ] downloadTaskWithURL: url];    [downloadTask resume];}

/ *
*最后,在我的委托方法中,在下载完成后(从临时数据移出文件后),我检查是否已完成,如果没有再次使用更新的索引计数器调用getfiles方法
* /

-(voID)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask dIDFinishDownloadingToURL:(NSURL *)location{    // Get the documents directory URL    NSArray *paths = NSSearchPathForDirectorIEsInDomains(NSdocumentDirectory,NSUserDomainMask,YES);    Nsstring *documentsDirectory = [paths objectAtIndex:0];    Nsstring *dataPath = [documentsDirectory stringByAppendingPathComponent:LOCAL_MEDIA_PATH];    NSURL *customDirectory = [NSURL fileURLWithPath:dataPath];    // Get the file name and create a destination URL    Nsstring *sendingfilename = [downloadTask.originalRequest.URL lastPathComponent];    NSURL *destinationUrl = [customDirectory URLByAppendingPathComponent:sendingfilename];    // Move the file    NSError *error = nil;    NSfileManager *fileManager = [NSfileManager defaultManager];    if ([fileManager moveItemAtURL:location toURL:destinationUrl error: &error]) {        // List        [self ListCustomDirectory];        if(downloadCounter < [REMOTE_MEDIA_file_PATHS count] -1) {            // Increment Counter            downloadCounter++;            // Start Next file            [self getfile:[REMOTE_MEDIA_file_PATHS objectAtIndex:downloadCounter]:downloadCounter];        }        else {            // FINISH YOUR OPERATION / NOTIFY USER / ETC        }    }    else {        NSLog(@"damn. Error %@",error);        // Do Something Intelligent Here    }  }
总结

以上是内存溢出为你收集整理的ios7 – iOS 7 NSURLSession在后台下载多个文件全部内容,希望文章能够帮你解决ios7 – iOS 7 NSURLSession在后台下载多个文件所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1113885.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存