暂停并恢复ASINetworkQueue

时间:2012-01-29 15:15:38

标签: ios asihttprequest nsoperationqueue

我正在使用ASINetworkQueue在iPad应用中下载大约50个文件。我正在寻找一种允许用户暂停和恢复队列的方法。

ASIHTTP文档引用

[request setAllowResumeForFileDownloads:YES];

但是它在单个请求级别运行,而不是在队列级别运行。由于ASINetworkQueue是NSOperationQueue的子类,我也尝试了

[queue setSuspended:YES];

虽然这会暂停一个队列,但它不会影响正在进行的下载,它只是等到它们完成然后暂停队列,在我的情况下意味着用户按下按钮和队列之间的间隔很短实际上是暂停,这不是我想要的UI体验。

有人能提出另一种解决这个问题的方法吗?

1 个答案:

答案 0 :(得分:0)

我的解决方案..

- (void) pause
{
    if(self.queue && self.queue.requestsCount>0)
    {
        NSLog(@"%@", self.queue.operations);

        for (ASIHTTPRequest * req in self.queue.operations) {
            req.userInfo = [NSDictionary dictionaryWithObject:@"1" forKey:@"ignore"];
        }

        [self.queue.operations makeObjectsPerformSelector:@selector(cancel)];

        [self.queue setSuspended:YES];

        for (ASIHTTPRequest * req in self.queue.operations) {
            ASIHTTPRequest * newReq = [[ASIHTTPRequest alloc] initWithURL:req.url];
            [newReq setDownloadDestinationPath:req.downloadDestinationPath];
            [newReq setTemporaryFileDownloadPath:req.temporaryFileDownloadPath];
//            [newReq setAllowResumeForFileDownloads:YES];
            [newReq setUserInfo:req.userInfo];
            [self.queue addOperation:newReq];

        }

    }
}

- (void) resume
{
    if(self.queue && self.queue.requestsCount>0)
    {
        [self _setupQueue];
        [self.queue go];
    }
}

- (void) _setupQueue
{
    [self.queue setShouldCancelAllRequestsOnFailure:NO];
    [self.queue setRequestDidStartSelector:@selector(downloadDidStart:)];
    [self.queue setRequestDidFinishSelector:@selector(downloadDidComplete:)];
    [self.queue setRequestDidFailSelector:@selector(downloadDidFailed:)];
    [self.queue setQueueDidFinishSelector:@selector(queueDidFinished:)];
    [self.queue setDownloadProgressDelegate:self.downloadProgress];
    [self.queue setDelegate:self];
    self.queue.maxConcurrentOperationCount = 3;
//    self.queue.showAccurateProgress = YES;
}

首先,暂停功能取消所有正在运行的操作,并重新创建新请求将它们推入队列。 然后恢复功能取消挂起队列。 请注意,请求不应设置setAllowResumeForFileDownloads:YES,否则totalBytesToDownload将计算错误。如果allowResumeForFileDownloads = NO,则其值将与队列中的请求数相同。

这是我的请求失败处理程序,我在文件下载失败时添加重试。但是,当我取消请求时,我不会忘记,重试机制将被调用,所以我设置userInfo(ignore:true)来请求对象以防止它发生。

- (void) downloadDidFailed:(ASIHTTPRequest *)req
{
    NSLog(@"request failed");
    NSLog(@"%d", self.queue.requestsCount);

    if(![self.queue showAccurateProgress])
    {
        [self.queue setTotalBytesToDownload:[self.queue totalBytesToDownload]-1];
        NSLog(@"totalBytesToDownload=%lld", self.queue.totalBytesToDownload);
    }

    NSDictionary * userInfo = req.userInfo;
    if([[userInfo valueForKey:@"ignore"] boolValue]) return; // ignore retry

    int retryTimes = [[req.userInfo objectForKey:@"retryTimes"] intValue];
    if(retryTimes<kMU_MaxRetry)
    {
        ++ retryTimes;
        NSLog(@"retry %d", retryTimes);
        ASIHTTPRequest * newReq = [ASIHTTPRequest requestWithURL:req.url];
        [newReq setDownloadDestinationPath:req.downloadDestinationPath];
        [newReq setTemporaryFileDownloadPath:req.temporaryFileDownloadPath];
        newReq.userInfo = [NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"%d", retryTimes] forKey:@"retryTimes"];
        [self.queue addOperation:newReq];

        NSLog(@"%d", self.queue.requestsCount);
    }else{  // reach max retry, fail it
        [self.failures addObject:req];
    }
}

我不确定是否有更好的解决方案,希望它可以帮到你。