3

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

如何取消或暂停 MKNetworkKit iOS 的下载操作?

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

方法

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

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

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

4

1 回答 1

0

在可冻结选项之外,据我所知,它不适用于 GET,标准 MKNetworkKit 中没有办法恢复下载。但是,稍作修改确实可以让您恢复已停止的下载

beginBackgroundTaskWithExpirationHandler

或通过

operationFailedWithError

它需要将下载的数据大小保存到另一个属性,比如 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 中时,它支持使用范围标头。

这似乎对我有用。我相信有更优雅的方式来做到这一点。

于 2014-02-19T10:32:55.360 回答