如何在网络出现故障时使用MKNetworkKit恢复下载

时间:2012-09-09 17:41:08

标签: objective-c ios mknetworkkit

据称,MKNetworkKit支持恢复中断的下载,但目前尚不清楚如何解决此问题。在另一个线程中,它的开发人员说,如果服务器发送Range标头,它就可以工作。

How to cancel or pause download operation of MKNetworkKit iOS?

但是,我的理解是发送Range标头的客户端。我希望图书馆能够看到已经下载了多少,然后请求适当的范围。我没有在代码中看到任何这样做的地方。

方法

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {

确实检查是否已指定Range,但似乎没有代码实际执行指定。

网络故障后有没有人让MKNetworkKit恢复下载?

1 个答案:

答案 0 :(得分:0)

在freezable选项之外,据我所知,GET不起作用,标准MKNetworkKit中没有办法恢复下载。但是,稍作修改可以让您恢复已被

停止的下载

beginBackgroundTaskWithExpirationHandler

operationFailedWithError

它需要将downloadedDataSize保存到另一个属性,例如resumeDownloadedDataSize,并通过诸如

之类的通知将其提供给调用对象
NSDictionary *resumeDownloadedDataSizeDetails = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithLong:self.resumeDownloadedDataSize], @"resumeDownloadedDataSize", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:kMKNetworkOperationEndBackgroundTaskWithExpirationHandler object:self userInfo:resumeDownloadedDataSizeDetails];

(在MkNetworkKit.h中定义kMKNetworkOperationEndBackgroundTaskWithExpirationHandler)

将resumeDownloadedDataSize设置为0,操作在没有错误或中断的情况下完成,并在您想要恢复时使其等于downloadDataSize。

然后添加

if (self.resumeDownloadedDataSize !=0) {

            NSString* range = @"bytes=";
            range = [range stringByAppendingString:[[NSNumber numberWithLong:self.resumeDownloadedDataSize] stringValue]];
            range = [range stringByAppendingString:@"-"];

            [[self request] setValue:range forHTTPHeaderField:@"Range"];
}

-(void) start

开头的这段代码
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {

    if (self.downloadedDataSize == 0) {
        // This is the first batch of data
        // Check for a range header and make changes as neccesary
        NSString *rangeString = [[self request] valueForHTTPHeaderField:@"Range"];
        if ([rangeString hasPrefix:@"bytes="] && [rangeString hasSuffix:@"-"]) {
            NSString *bytesText = [rangeString substringWithRange:NSMakeRange(6, [rangeString length] - 7)];
            self.startPosition = [bytesText integerValue];
            self.downloadedDataSize = self.startPosition;
        }
    }  

当客户端请求范围时,现在适用于我添加的偏移量。

我还添加了

@property (assign, nonatomic) NSUInteger resumeDownloadedDataSize;

到头文件,所以我可以从其他视图设置它。

现在,在您的通话对象中,您可以收听通知

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didMKNetworkOperationEndBackgroundTaskWithExpirationHandler:) name:kMKNetworkOperationEndBackgroundTaskWithExpirationHandler object:nil]; 

检查它并重新启动设置范围的操作。

- (void) didMKNetworkOperationEndBackgroundTaskWithExpirationHandler: (NSNotification*) notification
{
    if ([[notification object] isEqual:downloadOperation]) {
        resumeDownloadedDataSize = [notification.userInfo objectForKey:@"resumeDownloadedDataSize"];
        bDownloadOperationCancelled=YES;
    }
}

当我使用它进行大文件下载时,到期处理程序到期,当我回到前台时我重新开始操作。

if (bDownloadOperationCancelled) {
        NSLogDebug(@"DownloadOperationCancelled restarted");
        [self doFileDownload];
        bDownloadOperationCancelled=NO;
}

其中

- (void) doFileDownload
{
    downloadOperation = [ApplicationDelegate.downloadEngine downloadVideoFile:authDownloadURLString toFile:downloadPath withOffset:resumeDownloadedDataSize];
(Your code for handling completion blocks etc)
…

}

最后一部分是确保你的引擎中你设置为YES

[op addDownloadStream:[NSOutputStream outputStreamToFileAtPath:filePath append:YES]];

所以简历会添加到文件中。

还要清楚我正在使用AWS CloudFront,这支持在S3中存储数据时使用范围标题。

这似乎对我有用。我相信有更优雅的方式。